package com.xbongbong.paas.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.crm.help.FineClueHelp;
import com.xbongbong.formula.constant.Constant;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.business.rule.BusinessRuleInfoService;
import com.xbongbong.paas.business.rule.BusinessRuleUserPermissionHelp;
import com.xbongbong.paas.constant.LinkDisplayConstant;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.AttrTrashEntity;
import com.xbongbong.paas.domain.entity.BusinessRuleInfoEntity;
import com.xbongbong.paas.domain.entity.PaasAppEntity;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.PaasFormRefEntity;
import com.xbongbong.paas.domain.entity.PaasMenuEntity;
import com.xbongbong.paas.domain.entity.ProLinkBusinessEntity;
import com.xbongbong.paas.domain.entity.StageProcessEntity;
import com.xbongbong.paas.domain.entity.ext.CoOpPermsEntityExt;
import com.xbongbong.paas.domain.entity.ext.FieldPermissionEntityExt;
import com.xbongbong.paas.domain.entity.ext.OptionalRangeEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormExplainEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasMenuEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasProcessTemplateEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasProcessTemplateNodeEntityExt;
import com.xbongbong.paas.elasticsearch.util.XbbElasticsearchRestTemplate;
import com.xbongbong.paas.enums.BIProductEnum;
import com.xbongbong.paas.enums.BIProductReformEnum;
import com.xbongbong.paas.enums.ComboLinkFieldEnum;
import com.xbongbong.paas.enums.ComboTypeEnum;
import com.xbongbong.paas.enums.DefaultTypeEnum;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.EnableEnum;
import com.xbongbong.paas.enums.EsAliasEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.MenuTypeEnum;
import com.xbongbong.paas.enums.ModuleTypeEnum;
import com.xbongbong.paas.enums.NodeTypeEnum;
import com.xbongbong.paas.enums.PatternEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.enums.ProEsAliasEnum;
import com.xbongbong.paas.enums.ProcessSaasFormEnum;
import com.xbongbong.paas.enums.TitleSupportFieldEnum;
import com.xbongbong.paas.enums.bi.ChartSourceEnum;
import com.xbongbong.paas.enums.bi.XbbTableRefEnum;
import com.xbongbong.paas.factory.FieldOptimizationHandle;
import com.xbongbong.paas.feign.WorkOrderV2ExplainFeignClient;
import com.xbongbong.paas.field.BusinessFieldPojo;
import com.xbongbong.paas.field.CustomRecheckRulePojo;
import com.xbongbong.paas.field.DefaultAttrPoJo;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.ItemPoJo;
import com.xbongbong.paas.field.LinkFormPoJo;
import com.xbongbong.paas.field.LinkInfoPojo;
import com.xbongbong.paas.field.LinkListPojo;
import com.xbongbong.paas.field.LinkedAttrPoJo;
import com.xbongbong.paas.field.RelyConditionPoJo;
import com.xbongbong.paas.field.RelyPoJo;
import com.xbongbong.paas.field.SubFormPoJo;
import com.xbongbong.paas.help.CloudCodeHelp;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.help.FormDesignFormExplainHandleName;
import com.xbongbong.paas.help.PaasFormHelp;
import com.xbongbong.sys.help.PackageHelp;
import com.xbongbong.paas.help.ProFormHelp;
import com.xbongbong.paas.help.menu.InitCrmMenuHelp;
import com.xbongbong.paas.help.menu.ProMenuHelp;
import com.xbongbong.paas.help.permission.PermissionHelp;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.log.thread.LogThreadPoolBeanConfig;
import com.xbongbong.paas.lowcode.DeveloperService;
import com.xbongbong.paas.lowcode.LowCodeConfigService;
import com.xbongbong.paas.manager.feign.ChartResultFeignClient;
import com.xbongbong.paas.model.AttrTrashModel;
import com.xbongbong.paas.model.BusinessRuleInfoModel;
import com.xbongbong.paas.model.CustomButtonActionModel;
import com.xbongbong.paas.model.CustomButtonModel;
import com.xbongbong.paas.model.PaasAppModel;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.model.PaasFormRefModel;
import com.xbongbong.paas.model.PaasFormServiceModel;
import com.xbongbong.paas.model.PaasMenuModel;
import com.xbongbong.paas.model.PaasProcessDataModel;
import com.xbongbong.paas.model.PaasProcessNodeTaskModel;
import com.xbongbong.paas.model.PaasProcessTaskModel;
import com.xbongbong.paas.model.PaasProcessTemplateModel;
import com.xbongbong.paas.model.PaasProcessTemplateNodeModel;
import com.xbongbong.paas.model.ProLinkBusinessModel;
import com.xbongbong.paas.model.StageProcessModel;
import com.xbongbong.paas.pojo.FieldAttrEntityForDecisionInfo;
import com.xbongbong.paas.pojo.FormTitlePoJo;
import com.xbongbong.paas.pojo.PermissionComplexTermPojo;
import com.xbongbong.paas.pojo.ProductFieldPojo;
import com.xbongbong.paas.pojo.SelectedFormPojo;
import com.xbongbong.paas.pojo.SummaryDataPoJo;
import com.xbongbong.paas.pojo.SwitcherPojo;
import com.xbongbong.paas.pojo.SwitchsPojo;
import com.xbongbong.paas.pojo.dto.BusinessRuleWhiteDTO;
import com.xbongbong.paas.pojo.dto.CoUserPermissionListDTO;
import com.xbongbong.paas.pojo.dto.CoUserPermissionUpdateDTO;
import com.xbongbong.paas.pojo.dto.ComboLinkExplainListDTO;
import com.xbongbong.paas.pojo.dto.CustomRepeatLinkExplainDTO;
import com.xbongbong.paas.pojo.dto.FieldTypeListDTO;
import com.xbongbong.paas.pojo.dto.FormAddDTO;
import com.xbongbong.paas.pojo.dto.FormAllListDTO;
import com.xbongbong.paas.pojo.dto.FormDecisionInfoUpdateDTO;
import com.xbongbong.paas.pojo.dto.FormEntityAddDTO;
import com.xbongbong.paas.pojo.dto.FormEntityUpdateDTO;
import com.xbongbong.paas.pojo.dto.FormGetDTO;
import com.xbongbong.paas.pojo.dto.FormListDTO;
import com.xbongbong.paas.pojo.dto.FormRoleDetailDTO;
import com.xbongbong.paas.pojo.dto.FormRoleUpdateDTO;
import com.xbongbong.paas.pojo.dto.FormTitleListDTO;
import com.xbongbong.paas.pojo.dto.FormUpdateDTO;
import com.xbongbong.paas.pojo.dto.MenuFormCopyDTO;
import com.xbongbong.paas.pojo.dto.MenuFormDelDTO;
import com.xbongbong.paas.pojo.dto.UpdateExplainStageDTO;
import com.xbongbong.paas.pojo.dto.UserApproveListDTO;
import com.xbongbong.paas.pojo.vo.BusinessRuleWhiteVO;
import com.xbongbong.paas.pojo.vo.CoUserPermissionListVO;
import com.xbongbong.paas.pojo.vo.CoUserPermissionUpdateVO;
import com.xbongbong.paas.pojo.vo.ComboLinkExplainListVO;
import com.xbongbong.paas.pojo.vo.FieldTypeListVO;
import com.xbongbong.paas.pojo.vo.FormAddVO;
import com.xbongbong.paas.pojo.vo.FormAllListVO;
import com.xbongbong.paas.pojo.vo.FormAttrSetVO;
import com.xbongbong.paas.pojo.vo.FormDecisionInfoGetVO;
import com.xbongbong.paas.pojo.vo.FormEntityGetVO;
import com.xbongbong.paas.pojo.vo.FormExplainSimpleSetVo;
import com.xbongbong.paas.pojo.vo.FormGetVO;
import com.xbongbong.paas.pojo.vo.FormListVO;
import com.xbongbong.paas.pojo.vo.FormResultListVO;
import com.xbongbong.paas.pojo.vo.FormRoleDetailVO;
import com.xbongbong.paas.pojo.vo.FormRoleUpdateVO;
import com.xbongbong.paas.pojo.vo.FormSetVo;
import com.xbongbong.paas.pojo.vo.FormSimpleListVO;
import com.xbongbong.paas.pojo.vo.FormSimpleSetVO;
import com.xbongbong.paas.pojo.vo.FormTitleListVO;
import com.xbongbong.paas.pojo.vo.FormUpdateVO;
import com.xbongbong.paas.pojo.vo.MenuFormCopyVO;
import com.xbongbong.paas.pojo.vo.MenuListVO;
import com.xbongbong.paas.pojo.vo.PaasFormVo;
import com.xbongbong.paas.pojo.vo.UserApproveListVO;
import com.xbongbong.paas.pojo.vo.WorkOrderV2ComboVO;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.redis.RedisTimeConstant;
import com.xbongbong.paas.service.AssociationService;
import com.xbongbong.paas.service.CompanyConfigService;
import com.xbongbong.paas.service.EsignService;
import com.xbongbong.paas.service.FeeLogService;
import com.xbongbong.paas.service.FieldConvertRuleModel;
import com.xbongbong.paas.service.FieldIndexService;
import com.xbongbong.paas.service.FormConfigService;
import com.xbongbong.paas.service.HomePageManageService;
import com.xbongbong.paas.service.PaasAppService;
import com.xbongbong.paas.service.PaasFormExplainService;
import com.xbongbong.paas.service.PaasFormService;
import com.xbongbong.paas.service.PaasMenuService;
import com.xbongbong.paas.service.PackageService;
import com.xbongbong.paas.service.ProFormService;
import com.xbongbong.paas.service.TemplateService;
import com.xbongbong.paas.service.WorkReportSetService;
import com.xbongbong.paas.service.stage.StageHandle;
import com.xbongbong.paas.service.stage.StageHandleFactory;
import com.xbongbong.paas.service.stage.StageProcessService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.helper.ReflectHelper;
import com.xbongbong.paas.toolbox.pojo.AppPermissionPojo;
import com.xbongbong.paas.toolbox.pojo.ModulePermissionPojo;
import com.xbongbong.paas.toolbox.pojo.PermissionTermsPojo;
import com.xbongbong.paas.toolbox.thread.TransmittableThreadLocalUtil;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.BaseDTO;
import com.xbongbong.paas.toolbox.wrap.BaseVO;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.toolbox.wrap.XbbResponse;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.paas.util.FormUtil;
import com.xbongbong.pro.app.pojo.AppListReturnPojo;
import com.xbongbong.pro.businesstage.pojo.RuleEnablePojo;
import com.xbongbong.pro.businesstage.pojo.dto.RuleEnableDTO;
import com.xbongbong.pro.companyconfig.pojo.dto.CompanyConfigAddBatchDTO;
import com.xbongbong.pro.companyconfig.pojo.dto.CompanyConfigAddDTO;
import com.xbongbong.pro.constant.CommonConstant;
import com.xbongbong.pro.constant.ElasticConstant;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.constant.PackageConstant;
import com.xbongbong.pro.developer.pojo.dto.DeveloperVerifyDTO;
import com.xbongbong.pro.dictionary.pojo.DictionaryPojo;
import com.xbongbong.pro.domain.entity.AiAssistantEntity;
import com.xbongbong.pro.domain.entity.ChartCategoryEntity;
import com.xbongbong.pro.domain.entity.FieldConvertRuleEntity;
import com.xbongbong.pro.domain.entity.FormConfigEntity;
import com.xbongbong.pro.domain.entity.HomePageManageEntity;
import com.xbongbong.pro.domain.entity.LabelEntity;
import com.xbongbong.pro.domain.entity.LabelGroupEntity;
import com.xbongbong.pro.domain.entity.LinkProductRelyEntity;
import com.xbongbong.pro.enums.BusinessFineClueEnum;
import com.xbongbong.pro.enums.BusinessSearchEnum;
import com.xbongbong.pro.enums.ClueConverDefaultEnum;
import com.xbongbong.pro.enums.CompanyConfigDescribeEnum;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.FieldConvertDefaultEnum;
import com.xbongbong.pro.enums.FormListFilterTypeEnum;
import com.xbongbong.pro.enums.LabelNotEditEnum;
import com.xbongbong.pro.enums.PackageStatusEnum;
import com.xbongbong.pro.enums.PackageTypeEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.ShareSupportFormEnum;
import com.xbongbong.pro.enums.SummaryNotEditEnum;
import com.xbongbong.pro.enums.TitleNotEditEnum;
import com.xbongbong.pro.enums.ValueAddedTypeEnum;
import com.xbongbong.pro.enums.WorkReportEnum;
import com.xbongbong.pro.enums.errorcodes.ClueErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.ProErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.TemplateErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.UserTeamErrorCodeEnum;
import com.xbongbong.pro.enums.lowcode.ButtonTypeEnum;
import com.xbongbong.pro.enums.menu.enums.ProductMenuEnum;
import com.xbongbong.pro.enums.menu.enums.SystemAppMenuEnum;
import com.xbongbong.pro.enums.packages.enums.FeaturesEnum;
import com.xbongbong.pro.enums.packages.enums.PackageVersionEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.esign.pojo.dto.HasEsignDTO;
import com.xbongbong.pro.esign.pojo.vo.HasEsignVO;
import com.xbongbong.pro.form.pojo.CustomRepeatLinkExplainListPojo;
import com.xbongbong.pro.form.pojo.CustomRepeatLinkExplainPojo;
import com.xbongbong.pro.form.pojo.FieldEsIndexPoJo;
import com.xbongbong.pro.form.pojo.HomePagePoJo;
import com.xbongbong.pro.form.pojo.RuleTargetPojo;
import com.xbongbong.pro.form.pojo.dto.AllAppFormListDTO;
import com.xbongbong.pro.form.pojo.dto.AppFormListDTO;
import com.xbongbong.pro.form.pojo.dto.BusinessFieldDTO;
import com.xbongbong.pro.form.pojo.dto.ClueConvertRuleSaveDTO;
import com.xbongbong.pro.form.pojo.dto.ClueConvertRulesListDTO;
import com.xbongbong.pro.form.pojo.dto.ClueConvertRulesListSaveDTO;
import com.xbongbong.pro.form.pojo.dto.EnableAssociationListDTO;
import com.xbongbong.pro.form.pojo.dto.FieldConvertRuleDTO;
import com.xbongbong.pro.form.pojo.dto.FormAddBatchDTO;
import com.xbongbong.pro.form.pojo.dto.FormAssociationListDTO;
import com.xbongbong.pro.form.pojo.dto.FormBusinessRuleDTO;
import com.xbongbong.pro.form.pojo.dto.FormConfigAddBatchDTO;
import com.xbongbong.pro.form.pojo.dto.FormConfigAddDTO;
import com.xbongbong.pro.form.pojo.dto.FormDeleteDTO;
import com.xbongbong.pro.form.pojo.dto.FormRuleListDTO;
import com.xbongbong.pro.form.pojo.dto.FormUpdateBatchDTO;
import com.xbongbong.pro.form.pojo.dto.FormUpdateBusinessRuleDTO;
import com.xbongbong.pro.form.pojo.dto.FormUpdateNameDTO;
import com.xbongbong.pro.form.pojo.dto.HomePageDeleteDTO;
import com.xbongbong.pro.form.pojo.dto.HomePageUpdateDTO;
import com.xbongbong.pro.form.pojo.vo.AllAppFormListVO;
import com.xbongbong.pro.form.pojo.vo.BusinessFieldVO;
import com.xbongbong.pro.form.pojo.vo.ClueConvertRuleVO;
import com.xbongbong.pro.form.pojo.vo.CustomRepeatLinkExplainGetVO;
import com.xbongbong.pro.form.pojo.vo.EnableAssociationListVO;
import com.xbongbong.pro.form.pojo.vo.FieldConvertRuleVO;
import com.xbongbong.pro.form.pojo.vo.FormAddBatchVO;
import com.xbongbong.pro.form.pojo.vo.FormAssociationListVO;
import com.xbongbong.pro.form.pojo.vo.FormBusinessRuleVO;
import com.xbongbong.pro.form.pojo.vo.FormDeleteVO;
import com.xbongbong.pro.form.pojo.vo.FormRuleListVO;
import com.xbongbong.pro.form.pojo.vo.FormUpdateBatchVO;
import com.xbongbong.pro.form.pojo.vo.FormUpdateBusinessRuleVO;
import com.xbongbong.pro.form.pojo.vo.FormUpdateNameVO;
import com.xbongbong.pro.form.pojo.vo.HomePageListVO;
import com.xbongbong.pro.form.pojo.vo.SupportLinkageFieldsVO;
import com.xbongbong.pro.form.pojo.vo.UpdateExplainStageVO;
import com.xbongbong.pro.formexplain.pojo.LinkDataNumCheckPojo;
import com.xbongbong.pro.formexplain.pojo.RelatedLinkInfoPojo;
import com.xbongbong.pro.formexplain.pojo.ReturnExplainPojo;
import com.xbongbong.pro.formexplain.pojo.dto.FormExplainDeleteDTO;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.formexplain.pojo.vo.HandlerExplainVO;
import com.xbongbong.pro.homePageManage.pojo.dto.HomePageVisibleDTO;
import com.xbongbong.pro.homePageManage.pojo.vo.HomePageVisibleVO;
import com.xbongbong.pro.log.pojo.DetailLogPojo;
import com.xbongbong.pro.lowcodeconfig.pojo.dto.LowCodeConfigGetDTO;
import com.xbongbong.pro.lowcodeconfig.pojo.vo.LowCodeConfigGetVO;
import com.xbongbong.pro.menu.pojo.MenuReturnPojo;
import com.xbongbong.pro.menu.pojo.WorkReportQuickNewPojo;
import com.xbongbong.pro.menu.pojo.dto.MenuNewListDTO;
import com.xbongbong.pro.menu.pojo.dto.QuickNewListDTO;
import com.xbongbong.pro.menu.pojo.vo.MenuNewListVO;
import com.xbongbong.pro.menu.pojo.vo.QuickNewGetVO;
import com.xbongbong.pro.menu.pojo.vo.QuickNewListVO;
import com.xbongbong.pro.packageInfo.pojo.vo.BasePackageInfoVO;
import com.xbongbong.pro.permission.pojo.dto.VerifyViewPermissionDTO;
import com.xbongbong.pro.product.pojo.dto.FilterAttrOnOffJXCDTO;
import com.xbongbong.pro.recheck.pojo.RecheckAttrRulePojo;
import com.xbongbong.pro.recheck.pojo.RecheckFormRulePojo;
import com.xbongbong.pro.service.toolbox.smartsettings.help.SmartSettingsHelp;
import com.xbongbong.pro.service.toolbox.statistic.help.FormHelp;
import com.xbongbong.pro.statistic.constant.ChartConstant;
import com.xbongbong.pro.statistic.constant.RelatedProductConstant;
import com.xbongbong.pro.statistic.result.pojo.dto.ChartCategoryListByIdInDTO;
import com.xbongbong.pro.statistic.result.pojo.vo.ChartCategoryListByIdInVO;
import com.xbongbong.pro.template.pojo.dto.TemplateDTO;
import com.xbongbong.pro.thread.ThreadPoolBeanConfig;
import com.xbongbong.pro.workreportset.pojo.WorkReportSetVisibleRange;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.FormConfigConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.ClueConvertRuleEntity;
import com.xbongbong.saas.domain.entity.DataDictionaryEntity;
import com.xbongbong.saas.domain.entity.FormDataDictionaryEntity;
import com.xbongbong.saas.domain.entity.RecheckingRuleEntity;
import com.xbongbong.saas.domain.entity.ShareRuleEntity;
import com.xbongbong.saas.domain.entity.SignInSetEntity;
import com.xbongbong.saas.domain.entity.WorkOrderExplainEntity;
import com.xbongbong.saas.domain.entity.WorkOrderFormEntity;
import com.xbongbong.saas.domain.entity.WorkOrderTemplateEntity;
import com.xbongbong.saas.domain.entity.ext.WorkOrderExplainEntityExt;
import com.xbongbong.saas.domain.entity.ext.WorkOrderFormEntityExt;
import com.xbongbong.saas.domain.entity.ext.WorkOrderTemplateEntityExt;
import com.xbongbong.saas.enums.ClueRuleSettingEnum;
import com.xbongbong.saas.enums.CompanyConfigEnum;
import com.xbongbong.saas.enums.FormConfigEnum;
import com.xbongbong.saas.enums.LinkProductRelyEnum;
import com.xbongbong.saas.enums.MirrorModuleEnum;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperatePageEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.PayBalanceEnum;
import com.xbongbong.saas.enums.RedundantTemplateTypeEnum;
import com.xbongbong.saas.enums.RepeatTypeEnum;
import com.xbongbong.saas.enums.RuleSettingEnum;
import com.xbongbong.saas.enums.SaasButtonEnum;
import com.xbongbong.saas.enums.SelectProductEnum;
import com.xbongbong.saas.enums.ShowTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.XbbSetUpdateRuleEnum;
import com.xbongbong.saas.enums.business.ClueEnum;
import com.xbongbong.saas.enums.business.CommunicatePlanEnum;
import com.xbongbong.saas.enums.business.ContactEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.ContractOutstockEnum;
import com.xbongbong.saas.enums.business.CustomerCommunicateEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.DistributorEnum;
import com.xbongbong.saas.enums.business.OutstockEnum;
import com.xbongbong.saas.enums.business.PaySheetEnum;
import com.xbongbong.saas.enums.business.PaymentBalanceEnum;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import com.xbongbong.saas.enums.business.WorkReportFieldEnum;
import com.xbongbong.saas.enums.dictionary.CommunicateTypeEnum;
import com.xbongbong.saas.enums.dictionary.DictionaryEnum;
import com.xbongbong.saas.enums.dictionary.DictionarySpecialEnum;
import com.xbongbong.saas.enums.dictionary.DictionaryTermEnum;
import com.xbongbong.saas.help.LabelHelp;
import com.xbongbong.saas.help.SaasFormHelp;
import com.xbongbong.saas.help.StageHelp;
import com.xbongbong.saas.model.AiAssistantModel;
import com.xbongbong.saas.model.ClueConvertRuleModel;
import com.xbongbong.saas.model.DataDictionaryModel;
import com.xbongbong.saas.model.FormConfigModel;
import com.xbongbong.saas.model.FormDataDictionaryModel;
import com.xbongbong.saas.model.FormTemplateModel;
import com.xbongbong.saas.model.HomePageManageModel;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.model.LabelGroupModel;
import com.xbongbong.saas.model.LabelModel;
import com.xbongbong.saas.model.LinkProductRelyModel;
import com.xbongbong.saas.model.PaasFormDataModel;
import com.xbongbong.saas.model.ProductModel;
import com.xbongbong.saas.model.RecheckingRuleModel;
import com.xbongbong.saas.model.RefundModel;
import com.xbongbong.saas.model.SignInSetModel;
import com.xbongbong.saas.model.WorkOrderExplainModel;
import com.xbongbong.saas.model.WorkOrderFormModel;
import com.xbongbong.saas.model.WorkOrderTemplateModel;
import com.xbongbong.saas.service.FundSetService;
import com.xbongbong.saas.service.RecheckingRuleService;
import com.xbongbong.saas.service.ScoreRuleService;
import com.xbongbong.saas.service.StageInitService;
import com.xbongbong.saas.service.WorkOrderFormService;
import com.xbongbong.saas.service.toolbox.help.LogHelp;
import com.xbongbong.saas.service.toolbox.help.PackageStatusHelp;
import com.xbongbong.saas.service.toolbox.help.UpdatePackageRedisService;
import com.xbongbong.sys.domain.entity.CompanyConfigEntity;
import com.xbongbong.sys.domain.entity.CoverRoleEntity;
import com.xbongbong.sys.domain.entity.MirrorCompanyEntity;
import com.xbongbong.sys.domain.entity.MirrorInfoEntity;
import com.xbongbong.sys.domain.entity.ProPermissionEntity;
import com.xbongbong.sys.domain.entity.RoleEntity;
import com.xbongbong.sys.domain.entity.UserConfigEntity;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.enums.DataPermissionEnum;
import com.xbongbong.sys.enums.UserConfigEnum;
import com.xbongbong.sys.help.ProPermissionHelp;
import com.xbongbong.sys.model.CompanyConfigModel;
import com.xbongbong.sys.model.CoverRoleModel;
import com.xbongbong.sys.model.MirrorCompanyModel;
import com.xbongbong.sys.model.MirrorInfoModel;
import com.xbongbong.sys.model.ProPermissionModel;
import com.xbongbong.sys.model.RoleModel;
import com.xbongbong.sys.model.SharePermissionSetUserModel;
import com.xbongbong.sys.model.ShareRuleModel;
import com.xbongbong.sys.model.UserConfigModel;
import com.xbongbong.sys.pojo.DataPermissionDetailPojo;
import com.xbongbong.sys.pojo.DataPermissionsPojo;
import com.xbongbong.sys.pojo.DynamicPermissionPojo;
import com.xbongbong.sys.pojo.DynamicPermissionSubPojo;
import com.xbongbong.workflow.model.WorkflowModel;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.client.core.CountRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 * @author: wufeng
 * @date: 2018/8/13 17:35
 * @desrcption: 表单操作
 */
@Service("formService")
public class PaasFormServiceImpl implements PaasFormService {

    @Resource
    private TemplateService templateService;

    private static final Logger LOG = LoggerFactory.getLogger(PaasFormServiceImpl.class);

    private static final Integer FORM_LENGTH = 6;
    /**
     * 高级版全公司五对
     */
    private static final Integer PROFESSIONAL_USED_USER = 5*2;
    /**
     * 旗舰版每个公司50对
     */
    private static final Integer ULTIMATE = 50*2;
    /**
     * 旗舰版每个表单10对
     */
    private static final Integer FORM_ULTIMATE = 10*2;


    private static final List<Integer> BLOCK_LIST = Arrays.asList(XbbRefTypeEnum.PRICE_SET_PRODUCT.getCode(), XbbRefTypeEnum.PREPAYMENT_BALANCE.getCode(), XbbRefTypeEnum.PREPAY_BALANCE.getCode(), XbbRefTypeEnum.STOCK_PRODUCT.getCode(), XbbRefTypeEnum.BATCH_FLOW_BILL.getCode(), XbbRefTypeEnum.STOCK_FLOW_BILL.getCode(), XbbRefTypeEnum.SEQ_SEARCH.getCode(), XbbRefTypeEnum.STOCK_STANDING_BOOK.getCode(), XbbRefTypeEnum.CUSTOMER_STATEMENT.getCode(), XbbRefTypeEnum.CUSTOMER_STATEMENT_STATISTIC.getCode(), XbbRefTypeEnum.MARKETING_MANAGEMENT.getCode(), XbbRefTypeEnum.MARKETING_ACTIVITY.getCode(), XbbRefTypeEnum.PROMOTION_TOOL.getCode(), XbbRefTypeEnum.MARKETING_TOOL.getCode(), XbbRefTypeEnum.PROMOTION_ACTIVITY.getCode(), XbbRefTypeEnum.PROMOTION_ACTIVITY_MANAGEMENT.getCode(), XbbRefTypeEnum.MARKETING_ACTIVITY_MANAGEMENT.getCode(), XbbRefTypeEnum.CREDIT_CARD_BILL.getCode(), XbbRefTypeEnum.ONLINE_PAYMENT_FLOW.getCode(), XbbRefTypeEnum.SLA_LOG.getCode());
    /**
     * 关联条件数量
     */
    private static final Integer CONDITION_NUM = 5;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private RoleModel roleModel;
    @Resource
    private MongoLogHelp mongoLogHelp;
    @Resource
    private FormDesignFormExplainHandleName formDesignFormExplainHandleName;
    @Resource
    private PaasAppModel paasAppModel;
    @Resource
    private WorkOrderFormService workOrderFormService;
    @Resource
    private WorkOrderFormModel workOrderFormModel;
    @Resource
    private WorkOrderTemplateModel workOrderTemplateModel;
    @Resource
    private WorkOrderExplainModel workOrderExplainModel;
    @Resource
    private PaasMenuService paasMenuService;
    @Resource
    private PaasFormExplainService paasFormExplainService;
    @Resource
    private PaasMenuModel paasMenuModel;
    @Resource
    private WorkReportSetService workReportSetService;
    @Resource
    private ProPermissionModel proPermissionModel;
    @Resource
    private CoverRoleModel coverRoleModel;
    @Resource
    private FormConfigModel formConfigModel;
    @Resource
    private PaasAppService paasAppService;
    @Resource
    private CompanyConfigModel companyConfigModel;
    @Resource
    private CompanyConfigService companyConfigService;
    @Resource
    private PaasFormDataModel paasFormDataModel;
    @Resource
    private SmartSettingsHelp smartSettingsHelp;
    @Resource
    private XbbElasticsearchRestTemplate xbbElasticsearchRestTemplate;
    @Resource
    private PaasProcessTemplateModel paasProcessTemplateModel;
    @Resource
    private DataDictionaryModel dataDictionaryModel;
    @Resource
    private FormDataDictionaryModel formDataDictionaryModel;
    @Resource
    private LogHelp logHelp;
    @Resource
    private PaasFormHelp paasFormHelp;
    @Resource
    private PaasProcessTaskModel paasProcessTaskModel;
    @Resource
    private FormConfigService formConfigService;
    @Resource
    private PackageStatusHelp packageStatusHelp;
    @Resource
    private ProMenuHelp proMenuHelp;
    @Resource
    private MirrorInfoModel mirrorInfoModel;
    @Resource
    private MirrorCompanyModel mirrorCompanyModel;
    @Resource
    private PaasProcessTemplateNodeModel paasProcessTemplateNodeModel;
    @Resource
    private ProFormHelp proFormHelp;
    @Resource
    private ThreadPoolBeanConfig threadPoolBeanConfig;
    @Resource
    private AssociationService associationService;
    @Resource
    private PaasRedisHelper paasRedisHelper;
    @Resource
    private PaasProcessNodeTaskModel paasProcessNodeTaskModel;
    @Resource
    private PaasProcessDataModel paasProcessDataModel;
    @Resource
    private PackageService packageService;
    @Resource
    @Lazy
    private BusinessRuleUserPermissionHelp businessRuleUserPermissionHelp;
    @Resource
    private LinkProductRelyModel linkProductRelyModel;
    @Resource
    private BusinessRuleInfoService businessRuleInfoService;
    @Resource
    private FormTemplateModel formTemplateModel;
    @Resource
    private BusinessRuleInfoModel businessRuleInfoModel;
    @Resource
    private UserConfigModel userConfigModel;
    @Resource
    private PackageHelp packageHelp;
    @Resource
    private EsignService esignService;
    @Resource
    private ProLinkBusinessModel proLinkBusinessModel;
    @Resource
    private UpdatePackageRedisService updatePackageRedisService;
    @Resource
    private CloudCodeHelp cloudCodeHelp;
    @Resource
    private AiAssistantModel aiAssistantModel;
    @Resource
    private ChartResultFeignClient chartResultFeignClient;
    @Resource
    private RefundModel refundModel;
    @Resource
    private ProductModel productModel;
    @Resource
    private FundSetService fundSetService;
    @Resource
    private ClueConvertRuleModel clueConvertRuleModel;
    @Resource
    private ScoreRuleService scoreRuleService;
    @Resource
    private LabelModel labelModel;
    @Resource
    private LabelGroupModel labelGroupModel;
    @Resource
    private LabelHelp labelHelp;
    @Resource
    private SignInSetModel signInSetModel;
    @Resource
    private LowCodeConfigService lowCodeConfigService;
    @Resource
    private CustomButtonModel customButtonModel;
    @Resource
    private CustomButtonActionModel customButtonActionModel;
    @Resource
    private PaasFormServiceModel paasFormServiceModel;
    @Resource
    private DeveloperService developerService;
    @Resource
    private FieldConvertRuleModel fieldConvertRuleModel;
    @Resource
    private AttrTrashModel attrTrashModel;
    @Resource
    private PaasFormRefModel paasFormRefModel;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private WorkflowModel workflowModel;
    @Resource
    private SaasFormHelp saasFormHelp;
    @Resource
    private FormHelp formHelp;
    @Resource
    private LogThreadPoolBeanConfig logThreadPoolBeanConfig;
    @Resource
    private StageHandleFactory stageHandleFactory;
    @Resource
    private StageProcessModel stageProcessModel;
    @Resource
    private StageProcessService stageProcessService;
    @Resource
    private StageInitService stageInitService;
    @Resource
    private FineClueHelp fineClueHelp;
    @Resource
    private HomePageManageModel homePageManageModel;
    @Resource
    private HomePageManageService homePageManageService;
    @Resource
    private InitCrmMenuHelp initCrmMenuHelp;
    @Resource
    private FieldIndexService fieldIndexService;
    @Resource
    private IndexTypeModel indexTypeModel;
    @Resource
    private StageHelp stageHelp;
    @Resource
    private ProFormService proFormService;
    @Resource
    private FeeLogService feeLogService;
    @Resource
    private WorkOrderV2ExplainFeignClient workOrderV2ComboFeignClient;

    @Resource
    private RecheckingRuleService recheckingRuleService;
    @Resource
    private RecheckingRuleModel recheckingRuleModel;
    @Resource
    private ShareRuleModel shareRuleModel;
    @Resource
    private SharePermissionSetUserModel sharePermissionSetUserModel;

    @Override
    public FormAddVO add(FormAddDTO formAddDTO) throws XbbException {
        FormAddVO formAddVO = new FormAddVO();
        String userId = formAddDTO.getUserId();
        String corpid = formAddDTO.getCorpid();
        String userName = formAddDTO.getLoginUserName();
        PaasFormEntity paasFormEntity = new PaasFormEntity();
        try {
            FormEntityAddDTO formEntityAddDTO =formAddDTO.getFormAttr();
            //套餐判断
            if (Objects.equals(SaasMarkEnum.PAAS.getCode(), formEntityAddDTO.getSaasMark())) {
                Integer status = packageStatusHelp.getPackageStatus(corpid, ValueAddedTypeEnum.CUSTOM_FORM_NUM, 1);
                if(!Objects.equals(status, PackageStatusEnum.NORMAL.getCode()) && !Objects.equals(status, PackageStatusEnum.WARNING.getCode())){
                    throw new XbbException(ProErrorCodeEnum.API_ERROR_260014);
                }
            }

            if(SaasMarkEnum.SAAS.getCode().equals(formEntityAddDTO.getSaasMark()) &&
                    (Objects.equals(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), formEntityAddDTO.getBusinessType())
                    || Objects.equals(XbbRefTypeEnum.CONTRACT.getCode(), formEntityAddDTO.getBusinessType())
                            || Objects.equals(XbbRefTypeEnum.WORK_ORDER_V2.getCode(), formEntityAddDTO.getBusinessType()))) {

                TemplateDTO templateDTO = new TemplateDTO();
                templateDTO.setBusinessType(formEntityAddDTO.getBusinessType());
                templateDTO.setCorpid(corpid);
                templateService.checkNum(templateDTO);
            }
            BeanUtil.copyProperties(formEntityAddDTO, paasFormEntity);
            paasFormEntity.setCorpid(formAddDTO.getCorpid());
            paasFormEntity.setAppId(formAddDTO.getAppId());
            paasFormEntity.setCreatorId(formAddDTO.getUserId());
            paasFormEntity.setMenuId(formAddDTO.getMenuId());
            paasFormEntity.setName(formAddDTO.getName());
            paasFormEntity.setNameEn(formAddDTO.getNameEn());
            paasFormEntity.setCoOpPerms(JSONObject.toJSONString(formEntityAddDTO.getCoOpPerms()));
            paasFormEntity.setSummary(JSONObject.toJSONString(formEntityAddDTO.getSummaryEntity()));
            paasFormEntity.setLabels(JSONObject.toJSONString(formEntityAddDTO.getLabels()));
            paasFormEntity.setAssociationList(JSONObject.toJSONString(formEntityAddDTO.getAssociationList()));
            paasFormEntity.setSurcharge(JSONObject.toJSONString(formEntityAddDTO.getSurcharge()));
            paasFormEntity.setCustomTitle(JSONObject.toJSONString(formEntityAddDTO.getCustomTitle()));
            if(SaasMarkEnum.SAAS.getCode().equals(paasFormEntity.getSaasMark())) {
                paasFormEntity.setLabels(JSON.toJSONString(initCrmMenuHelp.getAppDefaultLabel(formEntityAddDTO.getBusinessType())));
                paasFormEntity.setCustomTitle(JSON.toJSONString(initCrmMenuHelp.getAppDefaultTitle(formEntityAddDTO.getBusinessType())));
                paasFormEntity.setSummary(JSON.toJSONString(initCrmMenuHelp.getAppDefaultSummary(formEntityAddDTO.getBusinessType())));
                paasFormEntity.setEnable(0);
            }
            // 新工单新建表单默认开始
            if (Objects.equals(XbbRefTypeEnum.WORK_ORDER_V2.getCode(),formEntityAddDTO.getBusinessType())){
                paasFormEntity.setEnable(1);
            }
            paasFormEntity.setBusinessRules(formAddDTO.getFormAttr().getBusinessRules());
            // 表单默认不隐藏
            paasFormEntity.setHidden(0);
            paasFormEntity.setSort(0);
            //客户/合同/销售 添加排序初始值
            setSort(paasFormEntity);
            paasFormModel.insert(paasFormEntity);
            //目前bi那边关联产品需求，如果当前业务有关联产品的话，就需要同步插入关联产品子表单以及产品子表单与主业务的关联关系
            List<BIProductReformEnum> biProductReformEnumList = BIProductReformEnum.getBIProductReformEnumByBus(formEntityAddDTO.getBusinessType());
            if (CollectionsUtil.isNotEmpty(biProductReformEnumList)) {
                List<PaasFormEntity> paasFormRefList = new ArrayList<>();
                paasFormRefList.add(paasFormEntity);
                Set<Integer> allBusinessTypes = BIProductReformEnum.getAllBusinessTypes();
                paasFormModel.insertSubProductFormList(paasFormRefList, allBusinessTypes);
            }
            formAddVO.setFormId(paasFormEntity.getId());
            String key = corpid + "_"+ ValueAddedTypeEnum.CUSTOM_FORM_NUM.getType();
            paasRedisHelper.removeValue(RedisPrefixConstant.VALUE_ADDED, key);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e){
            LOG.error("paasForm.add添加表单设计信息出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        // 日志
        String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_ADD_FORM), userName, paasFormEntity.getName());
        mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.PAAS_FORM, OperateTypeEnum.NEW, paasFormEntity.getId().toString(),
                paasFormEntity.getName(), memo, formAddDTO.getHttpHeader());

        return formAddVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public MenuFormCopyVO copy(MenuFormCopyDTO requestDTO) throws XbbException {
        MenuFormCopyVO responseVO = new MenuFormCopyVO();
        Integer saasMark = requestDTO.getSaasMark();
        Integer businessType = requestDTO.getBusinessType();
        String  userName = requestDTO.getLoginUserName();
        String  copyFormName = requestDTO.getName();
        String corpid = requestDTO.getCorpid();
        Long sourceFormId = requestDTO.getFormId();
        String userId = requestDTO.getUserId();
        Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("del", DelEnum.NORMAL.getDel());
        param.put("appId", requestDTO.getAppId());
        //校验业务类型 目前只有合同，销售机会，客户,线索支持复制
        checkTemplateType(saasMark,businessType);

        //校验表单名称是否已存在
        checkName(requestDTO);

        //校验该表单的数量是否超出6个
        checkFormCount(corpid,businessType,param);

        //复制表单的主表信息,返回源表单名称.
        PaasFormEntityExt sourceForm = insertFormInfo(responseVO,requestDTO);
        String sourceFormName = Objects.isNull(sourceForm.getName())?"-":sourceForm.getName();
        //插入成功之后，responseVO中会封装复制后的formId
        Long copyFormId = responseVO.getFormId();
        if(copyFormId == null){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        //复制表单解释
        insertExplain(responseVO,sourceFormId,corpid,userId,businessType);

        //复制业务规则
        insertBusinessRules(responseVO,corpid,sourceFormId,userId,param);

        //复制关联字段
        insertLinkBusinessField(sourceFormId,copyFormId,userId,param);

        // 复制"更新规则"
        insertRuleSetting(businessType, copyFormId, corpid, sourceFormId);

        // 复制阶段、输单原因
        insertStage(businessType , copyFormId , corpid, sourceFormId);

        if (Objects.equals(businessType, XbbRefTypeEnum.CONTRACT.getCode())) {
            // 复制关联回款限制、超发出库
            insertButtonConfig(copyFormId,corpid,sourceFormId,Arrays.asList(FormConfigEnum.CONTRACT_AMOUNT_EQUAL_REPAYMENT_PLAN.getConfig(),FormConfigEnum.CONTRACT_ALLOW_OUTSTOCK_PRODUCT_NUM_LARGER_SOLD.getConfig()));
        }

        if (Objects.equals(businessType, XbbRefTypeEnum.CLUE.getCode())) {
            // 复制线索表单，将线索的转换已有客户
            insertConvert(sourceFormId, copyFormId, corpid);
        }

        // 日志
        String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_COPY_FORM), userName, sourceFormName, copyFormName);
        mongoLogHelp.buildLog(corpid, requestDTO.getUserId(), userName, OperateModuleTypeEnum.PAAS_FORM, OperateTypeEnum.COPY, responseVO.getFormId().toString(),
                copyFormName, memo, requestDTO.getHttpHeader());
        return responseVO;
    }

    private void insertConvert(Long sourceFormId, Long copyFormId, String corpid) {
        List<ClueConvertRuleEntity> list = clueConvertRuleModel.getByCorpidAndFormId(corpid, sourceFormId);
        for(ClueConvertRuleEntity byCorpidAndFormId :list){
            if (Objects.isNull(byCorpidAndFormId)) {
                return;
            }
            byCorpidAndFormId.setFormId(copyFormId);
            byCorpidAndFormId.setId(null);
            try {
                clueConvertRuleModel.insert(byCorpidAndFormId);
            } catch (XbbException e) {
                LOG.error("复制线索表单，将线索的转换已有客户规则报错，", e);
            }
        }
    }

    private void insertLinkBusinessField(Long sourceFormId , Long copyFormId  , String userId , Map<String, Object> param){
        //查询源表单的关联字段
        param.put("formId",sourceFormId);
        List<ProLinkBusinessEntity> businessEntityList = proLinkBusinessModel.findEntitys(param);
        param.remove("formId");
        param.remove("columns");
        long now = DateUtil.getNow();
        if(CollectionsUtil.isNotEmpty(businessEntityList)){
            for(ProLinkBusinessEntity proLinkBusinessEntity : businessEntityList){
                proLinkBusinessEntity.setFormId(copyFormId);
                proLinkBusinessEntity.setCreatorId(userId);
                proLinkBusinessEntity.setAddTime(now);
                proLinkBusinessEntity.setUpdateTime(now);
            }
            proLinkBusinessModel.insertBatch(businessEntityList);
        }
    }

    private void insertStage(Integer businessType, Long copyFormId, String corpid, Long sourceFormId) {
        boolean isNeedCopyStageBusiness = Objects.equals(XbbRefTypeEnum.SALES_OPPORTUNITY.getCode(), businessType) ||
                Objects.equals(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), businessType) ||
                Objects.equals(XbbRefTypeEnum.CLUE.getCode(), businessType);
        if (isNeedCopyStageBusiness) {
            // 初始化阶段
            stageInitService.init(corpid, businessType, copyFormId);
            if (Objects.equals(businessType, XbbRefTypeEnum.SALES_OPPORTUNITY.getCode())) {
                //复制输单原因
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid", corpid);
                param.put("formId", sourceFormId);
                param.put("type", DictionarySpecialEnum.SALE_STAGE_WASTAGE.getDictionaryEnum().getType());
                param.put("del", DelEnum.NORMAL.getDel());
                long now = DateUtil.getInt();
                List<FormDataDictionaryEntity> dictionaryEntityList = formDataDictionaryModel.findEntitys(param);
                if (CollectionsUtil.isNotEmpty(dictionaryEntityList)) {
                    for (FormDataDictionaryEntity formDataDictionaryEntity : dictionaryEntityList) {
                        formDataDictionaryEntity.setFormId(copyFormId);
                        formDataDictionaryEntity.setAddTime(now);
                        formDataDictionaryEntity.setUpdateTime(now);
                    }
                    formDataDictionaryModel.insertBatch(dictionaryEntityList);
                }
            }
        }
    }

    private void insertRuleSetting(Integer businessType, Long copyFormId, String corpid, Long sourceFormId) {
        List<String> configs = RuleSettingEnum.getConfigs();
        if (Objects.equals(businessType, XbbRefTypeEnum.CLUE.getCode())) {
            configs = ClueRuleSettingEnum.getConfigs();
        }
        //复制表单"更新规则"
        insertButtonConfig(copyFormId, corpid, sourceFormId,configs);
    }

    private void insertButtonConfig(Long copyFormId , String corpid , Long sourceFormId ,List<String> configList){
        //复制按钮
        List<FormConfigEntity> formConfigEntity = formConfigModel.getButtonEntityByFormId(corpid , sourceFormId , configList);
        if(CollectionsUtil.isNotEmpty(formConfigEntity)){
            long now = DateTimeUtil.getInt();
            for(FormConfigEntity configEntity : formConfigEntity){
                configEntity.setFormId(copyFormId);
                configEntity.setAddTime(now);
                configEntity.setUpdateTime(now);
            }
            formConfigModel.insertBatch(formConfigEntity);
        }

    }

    private void checkTemplateType(Integer saasMark , Integer businessType) throws XbbException {
        if(!Objects.equals(SaasMarkEnum.SAAS.getCode(), saasMark) || !RedundantTemplateTypeEnum.isMultiTemplate(businessType)){
            throw new XbbException(TemplateErrorCodeEnum.API_ERROR_350003);
        }
    }

    private void checkName(MenuFormCopyDTO menuFormCopyDTO) throws XbbException {
        //校验表单名称不能为空
        if(Objects.isNull(menuFormCopyDTO.getName())){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.MENU_NAME_NOT_EMPTY);
        }
        //校验表单名称不能重复
        Map<String, Object> params = BeanUtil.convertBean2Map(menuFormCopyDTO,true);
        params.put("del",DelEnum.NORMAL.getDel());
        Integer count = paasFormModel.getEntitysCount(params);
        if(count>0){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.MENU_NAME_EXIST);
        }
    }

    private void checkFormCount(String corpid , Integer businessType , Map<String, Object> param) throws XbbException {


        TemplateDTO templateDTO = new TemplateDTO();
        templateDTO.setBusinessType(businessType);
        templateDTO.setCorpid(corpid);
        templateService.checkNum(templateDTO);
        //因为是复用的map,使用之后移除 非通用的参数
        param.remove("businessType");
        param.remove("columns");
        param.remove("orderByStr");
    }

    private PaasFormEntityExt insertFormInfo(MenuFormCopyVO responseVO , MenuFormCopyDTO requestDTO) throws XbbException {
        PaasFormEntity copyForm = new PaasFormEntity();
        PaasFormEntityExt sourceForm = paasFormModel.getByKey(requestDTO.getFormId(), requestDTO.getCorpid());
        if(Objects.isNull(sourceForm)){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
        }
        BeanUtils.copyProperties(sourceForm,copyForm);
        //表单名称, 是否开启流程设置，排序值 单独设置,创建人
        copyForm.setIsProcessForm(0);
        //关联列表不复制，因为"关联列表"关联的是原表单，这里筛入一个空的
        copyForm.setAssociationList(JSON.toJSONString(new JSONArray()));
        //复制的模板，默认是启用的
        copyForm.setEnable(1);
        copyForm.setName(requestDTO.getName());
        copyForm.setCreatorId(requestDTO.getUserId());
        setSort(copyForm);
        paasFormModel.insert(copyForm);
        //目前bi那边关联产品需求，如果当前业务有关联产品的话，就需要同步插入关联产品子表单以及产品子表单与主业务的关联关系
        List<BIProductReformEnum> biProductReformEnumList = BIProductReformEnum.getBIProductReformEnumByBus(copyForm.getBusinessType());
        if (CollectionsUtil.isNotEmpty(biProductReformEnumList)) {
            List<PaasFormEntity> paasFormRefList = new ArrayList<>();
            paasFormRefList.add(copyForm);
            Set<Integer> allBusinessTypes = BIProductReformEnum.getAllBusinessTypes();
            paasFormModel.insertSubProductFormList(paasFormRefList, allBusinessTypes);
        }
        responseVO.setFormId(copyForm.getId());
        responseVO.setMenuId(copyForm.getMenuId());
        responseVO.setFormName(requestDTO.getName());
        //返回源表单的名称，用做操作日志
       return sourceForm;
    }

    private void insertExplain(MenuFormCopyVO responseVO, Long sourceFormId , String corpid ,String userId, Integer businessType) throws XbbException {
        PaasFormExplainEntity explainEntity = paasFormExplainModel.getByFormId(sourceFormId, corpid);
        if(Objects.isNull(explainEntity)){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }
        // 表單是否有標簽字段
        Boolean flag = false;
        //去除表单解释中的智能助手，智能助手是不需要复制的（需求是这样的）
        List<FieldAttrEntity> explainList = JSONArray.parseArray(explainEntity.getExplains(), FieldAttrEntity.class);
        if(CollectionsUtil.isNotEmpty(explainList)){
            Iterator<FieldAttrEntity> iterator = explainList.iterator();
            while (iterator.hasNext()){
                FieldAttrEntity fieldAttrEntity = iterator.next();
                if(Objects.nonNull(fieldAttrEntity.getSmartSettingsNum())){
                    fieldAttrEntity.setSmartSettingsNum(null);
                }
                // 阶段推进器字段不复制多版本启用的设置
                if (Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.STAGE_THRUSTER.getType())) {
                    if (Objects.nonNull(fieldAttrEntity.getStageMultiVersion())) {
                        fieldAttrEntity.setStageMultiVersion(null);
                    }
                    if (Objects.nonNull(fieldAttrEntity.getDefaultStageProcessId())) {
                        fieldAttrEntity.setDefaultStageProcessId(null);
                    }
                }
                if (Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.LABEL.getType())){
                    flag = true;
                    DefaultAttrPoJo defaultAttrPoJo = new DefaultAttrPoJo();
                    defaultAttrPoJo.setDefaultType("custom");
                    fieldAttrEntity.setDefaultAttr(defaultAttrPoJo);
                }
                if (Objects.equals(BasicConstant.TWO, fieldAttrEntity.getIsOpen()) && Objects.equals(1, fieldAttrEntity.getIsRedundant())) {
                    // 将回收站的字段释放出来
                    iterator.remove();
                    continue;
                }
                if (ExplainUtil.isSubForm(fieldAttrEntity.getFieldType()) && Objects.nonNull(fieldAttrEntity.getSubForm())) {
                    Iterator<? extends FieldAttrEntity> subIterator = fieldAttrEntity.getSubForm().getItems().iterator();
                    while (subIterator.hasNext()) {
                        FieldAttrEntity item = subIterator.next();
                        if (Objects.equals(BasicConstant.TWO, item.getIsOpen()) && Objects.equals(1, item.getIsRedundant())) {
                            // 将回收站的字段释放出来
                            subIterator.remove();
                            continue;
                        }
                    }
                }
            }
            if (Objects.equals(businessType, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.CLUE.getCode())) {
                syncRepeatType(corpid, sourceFormId, explainList, businessType, responseVO);
            }
            explainEntity.setExplains(JSON.toJSONString(explainList));
        }
        // 复制的模板，默认是启用的
        explainEntity.setEnable(BasicConstant.IS_USE);
        explainEntity.setFormId(responseVO.getFormId());
        explainEntity.setCreatorId(userId);
        paasFormExplainModel.insert(explainEntity);
        responseVO.setFormExplainId(explainEntity.getId());
        // 复制标签 有标签字段的话后处理
        if (flag) {
            copyLable(responseVO, sourceFormId, userId, corpid);
        }
    }

    /**
     * 获取表单模板中名称和电话的查重配置
     */
    private void syncRepeatType(String corpid, Long formId, List<FieldAttrEntity> explainList, Integer businessType, MenuFormCopyVO responseVO) throws XbbException {
        String nameRepeatConfig = FormConfigEnum.CUSTOMER_NAME_REPEAT_TYPE.getConfig();
        String phoneRepeatConfig = FormConfigEnum.CUSTOMER_PHONE_REPEAT_TYPE.getConfig();
        String nameAttr = CustomerManagementEnum.NAME.getAttr();
        String phoneAttr = CustomerManagementEnum.PHONE.getAttr();
        if (Objects.equals(businessType, XbbRefTypeEnum.CLUE.getCode())) {
            nameRepeatConfig = FormConfigEnum.CLUE_NAME_REPEAT_TYPE.getConfig();
            phoneRepeatConfig = FormConfigEnum.CLUE_PHONE_REPEAT_TYPE.getConfig();
            nameAttr = ClueEnum.COMPANY_NAME.getAttr();
            phoneAttr = ClueEnum.PHONE.getAttr();
        }
        Long now = DateTimeUtil.getInt();
        List<FormConfigEntity> insertEntity = new ArrayList<>();
        for(FieldAttrEntity entity : explainList) {
            if (Objects.equals(entity.getAttr(), nameAttr)) {
                FormConfigEntity formConfigEntity = formConfigModel.getEntityByFormId(corpid, formId, nameRepeatConfig);
                if (formConfigEntity == null) {
                    entity.setCustomerNameRepeatType(RepeatTypeEnum.REPEAT_SINGLE.getType());
                } else {
                    String configValue = formConfigEntity.getConfigValue();
                    if (StringUtil.isNotEmpty(configValue)) {
                        entity.setCustomerNameRepeatType(Integer.valueOf(configValue));
                    }
                    formConfigEntity.setId(null);
                    formConfigEntity.setFormId(responseVO.getFormId());
                    formConfigEntity.setFormName(responseVO.getFormName());
                    formConfigEntity.setAddTime(now);
                    formConfigEntity.setUpdateTime(now);
                    insertEntity.add(formConfigEntity);
                }
                break;
            }
        }
        for(FieldAttrEntity entity : explainList) {
            if (Objects.equals(entity.getAttr(), phoneAttr)) {
                FormConfigEntity formConfigEntity = formConfigModel.getEntityByFormId(corpid, formId, phoneRepeatConfig);
                List<? extends FieldAttrEntity> items = entity.getSubForm().getItems();
                for (FieldAttrEntity item : items) {
                    if (Objects.equals(item.getAttr(), "text_2")) {
                        if (formConfigEntity == null) {
                            entity.setCustomerPhoneRepeatType(RepeatTypeEnum.REPEAT_SINGLE.getType());
                        } else {
                            String configValue = formConfigEntity.getConfigValue();
                            if (StringUtil.isNotEmpty(configValue)) {
                                entity.setCustomerPhoneRepeatType(Integer.valueOf(configValue));
                            }
                            formConfigEntity.setId(null);
                            formConfigEntity.setFormId(responseVO.getFormId());
                            formConfigEntity.setFormName(responseVO.getFormName());
                            formConfigEntity.setAddTime(now);
                            formConfigEntity.setUpdateTime(now);
                            insertEntity.add(formConfigEntity);
                        }
                        break;
                    }
                }
                break;
            }
        }
        if (CollectionsUtil.isNotEmpty(insertEntity)) {
            formConfigModel.insertBatch(insertEntity);
        }
    }

    /**
     * 复制标签
     * @param responseVO
     * @param sourceFormId
     * @param userId
     */
    private void copyLable(MenuFormCopyVO responseVO, Long sourceFormId, String userId, String corpid) {
        Long formId = responseVO.getFormId();
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("formId", sourceFormId);
        param.put("del", DelEnum.NORMAL.getDel());
        List<LabelGroupEntity> entitys = labelGroupModel.findEntitys(param);
        if (CollectionsUtil.isEmpty(entitys)) {
            return;
        }
        Map<String, Long> groupName2Id = new HashMap<>(entitys.size());
        Map<Long, Long> groupIdOld2New = new HashMap<>(entitys.size());
        entitys.forEach(item->{
            groupName2Id.put(item.getGroupName(), item.getId());
            item.setId(null);
            item.setFormId(formId);
            item.setCreatorId(userId);
        });
        if (entitys.size()>0) {
            labelGroupModel.insertBatch(entitys, corpid);
        }
        param.put("enable", 0);
        entitys.forEach(item->{
            Long aLong = groupName2Id.get(item.getGroupName());
            if (Objects.nonNull(aLong)){
                groupIdOld2New.put(aLong,item.getId());
            }
        });
        List<LabelEntity> labelEntities = labelModel.findEntitys(param);
        if (CollectionsUtil.isEmpty(labelEntities)) {
            return;
        }
        labelEntities.forEach(item->{
            item.setId(null);
            Long aLong = groupIdOld2New.get(item.getGroupId());
            if (Objects.nonNull(aLong)){
                item.setGroupId(aLong);
                item.setFormId(formId);
            }
        });
        labelModel.insertBatch(labelEntities, corpid);
    }


    private void insertBusinessRules(MenuFormCopyVO responseVO ,String corpid ,Long sourceFormId, String  userId,Map<String, Object> param) throws XbbException {
        //查询该公司办理的套餐
        Integer feeType = businessRuleUserPermissionHelp.getFeeType(corpid);
        //只有高级版旗舰版套餐有新增 业务规则
        if(Objects.equals(PackageTypeEnum.ADVANCED.getType(), feeType) ||Objects.equals(PackageTypeEnum.ULTIMATE.getType(), feeType)) {
            //companyCount: 查询该公司下的业务规则总数
            Integer companyCountInteger = businessRuleInfoModel.getEntitysCount(param);
            int companyCount = Objects.isNull(companyCountInteger) ? 0 : companyCountInteger.intValue();

            //formCount: 查询该公司下该种表单的业务规则总数
            param.put("formId", sourceFormId);
            Integer formCountInteger = businessRuleInfoModel.getEntitysCount(param);
            //源表单没有关联的业务规则，直接返回，前端不要展示报错提示信息
            if(Objects.isNull(formCountInteger)){
                return;
            }
            int formCount = formCountInteger.intValue();
            //totalCount： 提前计算复制之后该公司的业务规则总数，然后判断是否超出最大限制
            int totalCount = companyCount + formCount;
            //高级版：整个公司最多五条
            if (Objects.equals(PackageTypeEnum.ADVANCED.getType(), feeType)) {
                //该公司当前的业务规则总数+即将复制新增的业务规则数量 > 5 , 不需要复制
                if (totalCount > PROFESSIONAL_USED_USER) {
                    responseVO.setOverBusinessRuleCount(totalCount-PROFESSIONAL_USED_USER);
                    return;
                }
            }
            //标准版：公司下面不能超过五十条，并且公司下该种form表单关联的业务规则不能超过10条
            if (Objects.equals(PackageTypeEnum.ULTIMATE.getType(), feeType)) {
                //该公司当前的业务规则总数+即将复制新增的业务规则数量 > 50 , 不需要复制
                if (totalCount > ULTIMATE) {
                    responseVO.setOverBusinessRuleCount(totalCount-ULTIMATE);
                    return;
                }
            }
            //没有超过上限，走业务规则插入逻辑
            List<BusinessRuleInfoEntity> ruleInfoEntities = businessRuleInfoModel.findEntitys(param);
            param.remove("formId");
            if(!CollectionUtils.isEmpty(ruleInfoEntities)) {
                Long formId = responseVO.getFormId();
                for (BusinessRuleInfoEntity businessRuleInfoEntity : ruleInfoEntities) {
                    businessRuleInfoEntity.setFormId(formId);
                    businessRuleInfoEntity.setCreatorId(userId);
                    businessRuleInfoModel.insert(businessRuleInfoEntity);
                }
            }
        }
    }

    private void setSort(PaasFormEntity paasFormEntity){
        //客户/合同/销售 设置初始排序值
        if((!Objects.isNull(paasFormEntity)) && RedundantTemplateTypeEnum.isMultiTemplate(paasFormEntity.getBusinessType())){
            Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            map.put("corpid",paasFormEntity.getCorpid());
            map.put("businessType",paasFormEntity.getBusinessType());
            map.put("del",0);
            //查询该公司下的该业务下有效的表单
            map.put("orderByStr","sort");
            List<PaasFormEntity> effectiveFormEntityList = paasFormModel.findEntity(map);
            //集合为空，排序的初始值 为 1
            if(CollectionsUtil.isEmpty(effectiveFormEntityList)){
                paasFormEntity.setSort(1);
            }else{
                //最新加入的表单模板在最后面，排序值最大
                int size = effectiveFormEntityList.size();
                PaasFormEntity lastPassFormEntity  = effectiveFormEntityList.get(--size);
                Integer sort = lastPassFormEntity.getSort();
                paasFormEntity.setSort(++sort);
            }
        }
    }

    @Override
    public FormAddBatchVO addBatch(FormAddBatchDTO formAddBatchDTO) throws XbbException {
        return proFormService.addBatch(formAddBatchDTO);
    }

    @Override
    public FormUpdateBatchVO updateBatch(FormUpdateBatchDTO formUpdateBatchDTO) throws XbbException {
        FormUpdateBatchVO formUpdateBatchVO = new FormUpdateBatchVO();
        try {
            List<PaasFormEntity> formList = new ArrayList<>();
            if(Objects.nonNull(formUpdateBatchDTO) && Objects.nonNull(formUpdateBatchDTO.getFormList())){
                for(FormEntityUpdateDTO formEntityUpdateDTO: formUpdateBatchDTO.getFormList()) {
                    PaasFormEntity paasFormEntity = new PaasFormEntity();
                    paasFormEntity.setId(formEntityUpdateDTO.getId());
                    paasFormEntity.setAssociationList(JSONObject.toJSONString(formEntityUpdateDTO.getAssociationList()));
                    long now = DateUtil.getInt();
                    paasFormEntity.setUpdateTime(now);
                    formList.add(paasFormEntity);
                }
            }
            if(!formList.isEmpty()){
                String corpid = formUpdateBatchDTO.getCorpid();
                paasFormModel.updateBatch(formList, corpid);
                // 这段日志暂时没有太大作用 youli.chen
                /*if (Objects.equals(formUpdateBatchDTO.getCompanyInit(), 0)) {
                    String userName = formUpdateBatchDTO.getLoginUserName();
                    String userId = formUpdateBatchDTO.getUserId();
                    String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_UPDATE_FORM), userName, "");
                    mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.PAAS_FORM, OperateTypeEnum.EDIT, "", "", memo, formUpdateBatchDTO.getHttpHeader());
                }*/
            }
            formUpdateBatchVO.setFormList(formList);
        } catch (Exception e) {
            LOG.error("paasForm.updateBatch更新表单信息出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formUpdateBatchVO;
    }

    @Override
    public FormUpdateBatchVO updateBatch4Mirror(FormUpdateBatchDTO formUpdateBatchDTO) throws XbbException {
        FormUpdateBatchVO formUpdateBatchVO = new FormUpdateBatchVO();
        try {
            List<PaasFormEntity> formList = new ArrayList<>();
            if(Objects.nonNull(formUpdateBatchDTO) && Objects.nonNull(formUpdateBatchDTO.getFormList())){
                for(FormEntityUpdateDTO formEntityUpdateDTO: formUpdateBatchDTO.getFormList()) {
                    PaasFormEntity paasFormEntity = new PaasFormEntity();
                    BeanUtil.copyProperties(formEntityUpdateDTO, paasFormEntity);
                    paasFormEntity.setSurcharge(JSONObject.toJSONString(formEntityUpdateDTO.getSurcharge()));
                    paasFormEntity.setCustomTitle(JSONObject.toJSONString(formEntityUpdateDTO.getCustomTitle()));
                    paasFormEntity.setSummary(JSONObject.toJSONString(formEntityUpdateDTO.getSummary()));
                    paasFormEntity.setLabels(JSONObject.toJSONString(formEntityUpdateDTO.getLabels()));
                    paasFormEntity.setAssociationList(JSONObject.toJSONString(formEntityUpdateDTO.getAssociationList()));
                    long now = DateUtil.getInt();
                    paasFormEntity.setUpdateTime(now);
                    formList.add(paasFormEntity);
                }
            }
            if(!formList.isEmpty()){
                String corpid = formUpdateBatchDTO.getCorpid();
                paasFormModel.updateBatch(formList, corpid);
                //因为这边更新、删除实际对数据库的操作都是更新操作，这边删除主业务操作的时候我们需要同步删除一下与这个主业务关联的产品子表单
                handleDeletePaasForm(formList, corpid);
                // 这段日志暂时没有太大作用 youli.chen
                /*if (Objects.equals(formUpdateBatchDTO.getCompanyInit(), 0)) {
                    String userName = formUpdateBatchDTO.getLoginUserName();
                    String userId = formUpdateBatchDTO.getUserId();
                    String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_UPDATE_FORM), userName, "");
                    mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.PAAS_FORM, OperateTypeEnum.EDIT, "", "", memo, formUpdateBatchDTO.getHttpHeader());
                }*/
            }
            formUpdateBatchVO.setFormList(formList);
        } catch (Exception e) {
            LOG.error("paasForm.updateBatch更新表单信息出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formUpdateBatchVO;
    }

    /**
     * 处理删除的表单
     *
     * @param formList 所有的表单列表
     * @param corpid 公司id
     */
    private void handleDeletePaasForm(List<PaasFormEntity> formList, String corpid) {
        List<Long> shouldDeleteIdList = new ArrayList<>();
        formList.forEach(paasFormEntity -> {
            if (Objects.equals(paasFormEntity.getDel(), BasicConstant.ONE)) {
                shouldDeleteIdList.add(paasFormEntity.getId());
            }
        });
        if (CollectionsUtil.isNotEmpty(shouldDeleteIdList)) {
            Map<String, Object> paasFormRefMap = new HashMap<>();
            paasFormRefMap.put("del", BasicConstant.ZERO);
            paasFormRefMap.put("mainFormIdS", shouldDeleteIdList);
            paasFormRefMap.put("corpid", corpid);
            List<PaasFormRefEntity> paasFormRefEntities = paasFormRefModel.findEntitys(paasFormRefMap);
            if (CollectionsUtil.isNotEmpty(paasFormRefEntities)) {
                List<Long> paasFormRefIdList = paasFormRefEntities.stream().map(e -> e.getId()).collect(Collectors.toList());
                List<Long> subProductFormIdList = paasFormRefEntities.stream().map(e -> e.getFormId()).collect(Collectors.toList());
                paasFormRefModel.deleteBatch(paasFormRefIdList, corpid);
                paasFormModel.deleteBatch(subProductFormIdList, corpid);
            }
        }
    }

    @Override
    public FormGetVO get(FormGetDTO formGetDTO) throws XbbException{
        FormGetVO formGetVO = new FormGetVO();
        try {
            String corpid = formGetDTO.getCorpid();
            PaasFormEntityExt paasFormEntityExt = new PaasFormEntityExt();
            PaasFormExplainEntity paasFormExplainEntity = new PaasFormExplainEntity();
            if (Objects.equals(formGetDTO.getBusinessType(), XbbRefTypeEnum.WORK_ORDER.getCode())) {
                WorkOrderFormEntityExt workOrderFormEntityExt = workOrderFormModel.getByKey(formGetDTO.getFormId(), corpid);
                WorkOrderExplainEntityExt workOrderExplainEntityExt = workOrderExplainModel.getByFormId(formGetDTO.getFormId(), corpid);
                BeanUtil.copyProperties(workOrderFormEntityExt, paasFormEntityExt);
                paasFormEntityExt.setBusinessType(XbbRefTypeEnum.WORK_ORDER.getCode());
                paasFormEntityExt.setSaasMark(SaasMarkEnum.SAAS.getCode());
                if (Objects.equals(LocaleContextHolder.getLocale().getLanguage(), I18nStringConstant.ENGLISH_LANGUAGE)) {
                    paasFormEntityExt.setName(workOrderFormEntityExt.getNameEn());
                    paasFormEntityExt.setNameEn(workOrderFormEntityExt.getName());
                }
                BeanUtil.copyProperties(workOrderExplainEntityExt, paasFormExplainEntity);
                formGetVO.setBusinessType(XbbRefTypeEnum.WORK_ORDER.getCode());
            } else {
                // 查看表单主表信息
                paasFormEntityExt = paasFormModel.getByKey(formGetDTO.getFormId(), corpid);
                // 查看表单字段描述信息
                 paasFormExplainEntity = paasFormExplainModel.getByFormId(formGetDTO.getFormId(), corpid);
            }
            if (Objects.isNull(paasFormEntityExt) || Objects.equals(paasFormEntityExt.getDel(),DelEnum.DELETE.getDel())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
            }
            if (Objects.isNull(paasFormExplainEntity) || Objects.equals(paasFormExplainEntity.getDel(),DelEnum.DELETE.getDel())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
            //根据应收规则，处理表单模板（防止模板字段未和最新的应收规则匹配，保存前做一次处理）
            fundSetService.handleSpecialExplain(corpid, paasFormExplainEntity);
            FormEntityGetVO formEntityGetVO = new FormEntityGetVO();
            BeanUtils.copyProperties(paasFormEntityExt, formEntityGetVO);
            if (commonHelp.isOpenWorkFlow(corpid)) {
                Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                params.put(StringConstant.CORPID, corpid);
                params.put(StringConstant.FORM_ID, paasFormEntityExt.getId());
                params.put(StringConstant.BUSINESS_TYPE, paasFormEntityExt.getBusinessType());
                params.put("currentVersion", 1);
                params.put("isApprove", 1);
                params.put("enable", 1);
                Integer count = workflowModel.getEntitysCount(params);
                if (count > 0) {
                    formEntityGetVO.setProcessEnable(1);
                }
            } else {
                Map<String, Object> params = BeanUtil.convertBean2Map(formGetDTO, true);
                params.put("enable", 1);
                params.put(ParameterConstant.COLUMNS, " enable ");
                List<PaasProcessTemplateEntityExt> templateList = paasProcessTemplateModel.list(params);
                if (!templateList.isEmpty()) {
                    formEntityGetVO.setProcessEnable(1);
                }
            }

            formEntityGetVO.setCoOpPerms(JSON.parseObject(paasFormEntityExt.getCoOpPerms(), CoOpPermsEntityExt.class));
            List<FieldAttrEntity> explainList =  JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
            // 16632 【web-访客计划】字段权限“可编辑”对表单中的所有字段不起作用（访客计划特殊逻辑，因无法编辑，需要禁用可编辑设置）
            if(Objects.equals(formEntityGetVO.getBusinessType(), XbbRefTypeEnum.COMMUNICATE_PLAN.getCode())) {
                for(FieldAttrEntity entity : explainList) {
                    entity.setShowEditable(BasicConstant.NO_USE);
                }
            } else {
                ExplainUtil.setShowEditable(formGetDTO.getBusinessType(), explainList);
            }
            if(Objects.equals(XbbRefTypeEnum.PRODUCT.getCode(), paasFormEntityExt.getBusinessType()) || Objects.equals(XbbRefTypeEnum.REFUND.getCode(), paasFormEntityExt.getBusinessType())) {
                Boolean enable = paasAppService.validateAppEnable(paasFormEntityExt.getAppId(), XbbRefTypeEnum.PRODUCT.getAlias(), paasFormEntityExt.getSaasMark(), corpid);
                JSONObject saasObj = new JSONObject();
                saasObj.put("isJxcUse", enable);
                formGetVO.setSaasObj(saasObj);
            }
            // saas业务解释特殊处理
            saasHandel(formGetDTO, explainList, null);
            // 关联产品之间数据联动封装到解释里
            linkProductRelyHandel(formGetDTO, corpid, explainList);
            Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(paasFormExplainEntity.getExplains(), null);
            List<SummaryDataPoJo> summaryEntity = JSONArray.parseArray(paasFormEntityExt.getSummary(), SummaryDataPoJo.class);
            summaryEntity = summaryEntity == null ? new ArrayList<>() : summaryEntity;
            for (SummaryDataPoJo summaryDataPoJo : summaryEntity) {
                FieldAttrEntity fieldAttrEntity = explainMap.get(summaryDataPoJo.getAttr());
                if (fieldAttrEntity == null) {
                    continue;
                }
                summaryDataPoJo.setFieldType(explainMap.get(summaryDataPoJo.getAttr()).getFieldType());
                summaryDataPoJo.setAttrName(explainMap.get(summaryDataPoJo.getAttr()).getAttrName());
                summaryDataPoJo.setValue(new ArrayList<>());
            }

            formEntityGetVO.setSummary(summaryEntity);
            List<SummaryDataPoJo> labels = JSONArray.parseArray(paasFormEntityExt.getLabels(), SummaryDataPoJo.class);
            labels = labels == null ? new ArrayList<>() : labels;
            for (SummaryDataPoJo item : labels) {
                FieldAttrEntity fieldAttrEntity = explainMap.get(item.getAttr());
                if (fieldAttrEntity == null) {
                    continue;
                }
                item.setFieldType(fieldAttrEntity.getFieldType());
                item.setAttrName(fieldAttrEntity.getAttrName());
                item.setValue(new ArrayList<>());
            }
            List<FormTitlePoJo> titleList = JSONArray.parseArray(paasFormEntityExt.getCustomTitle(), FormTitlePoJo.class);
            if (Objects.isNull(titleList)) {
                titleList = new ArrayList<>();
            }
            for(FormTitlePoJo item: titleList) {
                FieldAttrEntity fieldAttrEntity = explainMap.get(item.getAttr());
                if (fieldAttrEntity == null) {
                    continue;
                }
                item.setAttrName(fieldAttrEntity.getAttrName());
                item.setValue(new ArrayList<>());
            }
            if (Objects.equals(paasFormEntityExt.getSaasMark(), SaasMarkEnum.SAAS.getCode())) {
                SummaryNotEditEnum summaryNotEditEnum = SummaryNotEditEnum.getByType(paasFormEntityExt.getBusinessType());
                if (Objects.nonNull(summaryNotEditEnum)) {
                    formEntityGetVO.setSummaryEditable(0);
                }
                TitleNotEditEnum titleNotEditEnum = TitleNotEditEnum.getByType(paasFormEntityExt.getBusinessType());
                if (Objects.nonNull(titleNotEditEnum)) {
                    formEntityGetVO.setTitleEditable(0);
                }
                LabelNotEditEnum labelNotEditEnum = LabelNotEditEnum.getByType(paasFormEntityExt.getBusinessType());
                if (Objects.nonNull(labelNotEditEnum)) {
                    formEntityGetVO.setLabelEditable(0);
                }
            }
            formEntityGetVO.setCustomTitle(titleList);
            formEntityGetVO.setLabels(labels);
            formEntityGetVO.setSaasMark(paasFormEntityExt.getSaasMark());
            formEntityGetVO.setBusinessType(paasFormEntityExt.getBusinessType());
            formEntityGetVO.setFieldPosition(paasFormEntityExt.getFieldPosition());
            //根据业务塞入表单设置的开关
            formatCompanySetSwitchs(formEntityGetVO,paasFormEntityExt.getSaasMark());
            formatFormSetSwitchs(formEntityGetVO);
            // 联系人设置项目决策信息入口
            if (Objects.equals(formGetDTO.getBusinessType(), XbbRefTypeEnum.CONTACT.getCode())) {
                boolean decisionTree = false;
                Integer feeType = businessRuleUserPermissionHelp.getFeeType(corpid);
                if (Objects.equals(PackageTypeEnum.ULTIMATE.getType(), feeType)) {
                    decisionTree = true;
                }
                formEntityGetVO.setDecisionTree(decisionTree);
            }


            // 设置智能助手数据(saasMark=1设置，paas先不添加－－消息paas应用还没实现)
            if (Objects.equals(SaasMarkEnum.SAAS.getCode(), paasFormEntityExt.getSaasMark())) {
                smartSettingsHelp.setSsNumForExplain(formGetDTO.getCorpid(), formGetDTO.getFormId(), explainList);
            }

            HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
            BeanUtil.copyProperties(formGetDTO, handlerExplainDTO);
            handlerExplainDTO.setExplainList(explainList);
            handlerExplainDTO.setPaasFormEntityExt(paasFormEntityExt);
            HandlerExplainVO handlerExplainVO = formDesignFormExplainHandleName.handleExplain(handlerExplainDTO);
            formGetVO.setAppId(formGetDTO.getAppId());
            formGetVO.setFormAttr(formEntityGetVO);
            formGetVO.setFormId(paasFormEntityExt.getId());
            formGetVO.setExplainList(handlerExplainVO.getHeadList());
            formGetVO.setFormExplainId(paasFormExplainEntity.getId());

            // 手机号码等正则枚举类
            formGetVO.setPatternList(PatternEnum.list());

            // CRM 简化版表单配置
            boolean formAttrFlag = false;
            List<SwitchsPojo> switches = formEntityGetVO.getSwitchs();
            if (Objects.nonNull(switches) && switches.size() > 0) {
                formAttrFlag = true;
            }
            getSimpleCRMFormSet(corpid, formGetVO, formAttrFlag, formGetDTO.getBusinessType());
            // 表单可以设置业务规则，并且未开启工作流才能在界面上看到业务规则设置入口
            Boolean useBusinessRule = FormUtil.haveUserPermission(paasFormEntityExt.getBusinessType(), paasFormEntityExt.getSaasMark(), paasFormEntityExt.getDistributorMark());
            if (useBusinessRule) {
                // 有业务规则
                Integer count = businessRuleInfoModel.countByFormId(paasFormEntityExt.getId(), paasFormEntityExt.getCorpid(), paasFormEntityExt.getBusinessType());

                Integer feeType = packageService.getFeeType(corpid);
                List<String> featureList = PackageVersionEnum.getFeatureList(feeType);
                useBusinessRule = featureList.contains(FeaturesEnum.BUSINESS_RULE.getAlias());
                if (useBusinessRule) {
                    Boolean exceeded = updatePackageRedisService.businessRuleExceeded(corpid, feeType);
                    formGetVO.setExceeded(exceeded);
                    if (exceeded) {
                        formGetVO.setMessage(I18nMessageUtil.getMessage(PackageConstant.PACKAGE_LIMIT_BUSINESS_RULE_MESSAGE));
                    }
                }
                if (Objects.equals(0, count) && commonHelp.isOpenWorkFlow(corpid)) {
                    // 如果有工作流，且当前表单业务规则条件为0时，将隐藏业务规则设置入口
                    useBusinessRule = false;
                }
            }
            formGetVO.setUseBusinessRule(useBusinessRule);
            // 国际化白名单
            CompanyConfigEntity entity = companyConfigModel.getByConfigAlias(CompanyConfigEnum.I18N_WHITE.getAlias(), PaasConstant.DEFAULT_DATA_CORPID);
            String value = CompanyConfigEnum.I18N_WHITE.getValue();
            if (Objects.nonNull(entity)) {
                value = entity.getConfigValue();
            }
            List<String> whiteList = JsonHelperUtil.parseArray(value, String.class);
            boolean flag = CollectionsUtil.isNotEmpty(whiteList) && whiteList.contains(corpid);
            formGetVO.setMultiLang(flag);

            // 查看是否能使用精线索的工商模糊查询
            boolean fineClueFlag = fineClueHelp.isBusinessSearch(corpid, formGetDTO.getBusinessType(), formGetDTO.getDistributorMark());
            int isFineClue = fineClueFlag ? BasicConstant.ONE : BasicConstant.ZERO;
            formGetVO.setIsFineClue(isFineClue);
            LowCodeConfigGetDTO lowCodeConfigGetDTO = new LowCodeConfigGetDTO();
            lowCodeConfigGetDTO.setCorpid(corpid);
            lowCodeConfigGetDTO.setFormId(formGetDTO.getFormId());
            lowCodeConfigGetDTO.setBusinessType(formGetDTO.getBusinessType());
            lowCodeConfigGetDTO.setLoginUser(formGetDTO.getLoginUser());
            lowCodeConfigGetDTO.setType(ButtonTypeEnum.DETAIL.getCode());
            LowCodeConfigGetVO lowCodeConfig = lowCodeConfigService.get(lowCodeConfigGetDTO);

            formGetVO.setLowCodeConfig(lowCodeConfig);
            DeveloperVerifyDTO developerVerifyDTO = new DeveloperVerifyDTO();
            developerVerifyDTO.setCorpid(corpid);
            developerVerifyDTO.setFormId(formGetDTO.getFormId());
            developerVerifyDTO.setBusinessType(formGetDTO.getBusinessType());
            developerVerifyDTO.setLoginUser(formGetDTO.getLoginUser());
            developerVerifyDTO.setUserId(formGetDTO.getUserId());
            developerVerifyDTO.setSaasMark(paasFormEntityExt.getSaasMark());
            boolean devPermission = developerService.hasDeveloperPermission(developerVerifyDTO);
            formGetVO.setDevPermission(devPermission);

            // 是否启用字段映射，目前就线索表单有
            if (Objects.equals(formGetDTO.getBusinessType(), XbbRefTypeEnum.CLUE.getCode())) {
                formGetVO.setUseFieldConvertRule(true);
            }
            // 预览时关联产品下拉初始化
            /*if (Objects.equals(SaasMarkEnum.SAAS.getCode(), paasFormEntityExt.getSaasMark())) {
                FormatExplainDTO formatExplainDTO = new FormatExplainDTO();
                BeanUtil.copyProperties(formGetDTO, formatExplainDTO);
                formatExplainDTO.setExplainList(explainList);
                saasAddHelp.formatExplain(formatExplainDTO);
            }*/

            //当前公司是否支持列表页展示阶段停留时长功能
            if (stageHelp.isSupportStageStayTime(corpid)) {
                formGetVO.setIsSupportStageStayTime(BasicConstant.ONE);
            }

            Map<String, Object> param = new HashMap<>();
            param.put("corpid", corpid);
            param.put("menuId", formGetDTO.getMenuId());
            param.put("formId", formGetDTO.getFormId());
            param.put("appId", formGetDTO.getAppId());
            param.put("recover", 0);
            param.put("del", 0);
            List<AttrTrashEntity> attrTrashEntityList = attrTrashModel.findEntitys(param);
            Set<String> trashList = new HashSet<>();
            attrTrashEntityList.forEach(v -> trashList.add(v.getAttr()));
            formGetVO.setTrashList(trashList);
            Map<String, Map<String, FieldEsIndexPoJo>> esIndexMap = fieldIndexService.getFieldIndexNum(corpid, paasFormEntityExt.getSaasMark(), paasFormEntityExt.getBusinessType(), paasFormEntityExt.getDistributorMark(), paasFormEntityExt.getId());
            formGetVO.setFieldMap(esIndexMap.get("field"));
            formGetVO.setSubFieldMap(esIndexMap.get("subField"));
            // 是否开通过断点续传的白名单用户
            CompanyConfigEntity companyConfigEntity = companyConfigModel.getByConfigAlias(CompanyConfigEnum.UPLOAD_LIMIT_SIZE.getAlias(), formGetDTO.getCorpid());
            Boolean isUploadLimitWhite = Objects.nonNull(companyConfigEntity);
            formGetVO.setIsUploadLimitWhite(isUploadLimitWhite);

            FormConfigEntity formConfigEntity = formConfigModel.getByConfig(RedisPrefixConstant.ASSIGNMENT_RULES, corpid, formGetDTO.getFormId(), paasFormEntityExt.getSaasMark(), paasFormEntityExt.getBusinessType());
            if (Objects.nonNull(formConfigEntity)) {
                formGetVO.getFormAttr().setAssignmentRules(Integer.valueOf(formConfigEntity.getConfigValue()));
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasForm数据库查询出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formGetVO;
    }

    @Override
    public FormDecisionInfoGetVO decisionInfoGet(FormGetDTO formGetDTO) throws XbbException {
        FormDecisionInfoGetVO decisionInfoVO = new FormDecisionInfoGetVO();
        String corpid = formGetDTO.getCorpid();
        try {
            PaasFormEntityExt paasFormEntityExt = paasFormModel.getByBusinessType(XbbRefTypeEnum.PROJECT_DECISION_INFO.getCode(), corpid);
            if (Objects.isNull(paasFormEntityExt)) {
                initCrmMenuHelp.setDecisionInfoFormAndExplain(formGetDTO.getAppId(), corpid, null);
                paasFormEntityExt = paasFormModel.getByBusinessType(XbbRefTypeEnum.PROJECT_DECISION_INFO.getCode(), corpid);
            }
            if (Objects.equals(paasFormEntityExt.getDel(),DelEnum.DELETE.getDel())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
            }
            // 查看表单字段描述信息
            PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(paasFormEntityExt.getId(), corpid);

            if (Objects.isNull(paasFormExplainEntity) || Objects.equals(paasFormExplainEntity.getDel(),DelEnum.DELETE.getDel())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
            List<FieldAttrEntityForDecisionInfo> explainList =  JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntityForDecisionInfo.class);

            decisionInfoVO.setBusinessType(formGetDTO.getBusinessType());
            FormEntityGetVO formEntityGetVO = new FormEntityGetVO();
            BeanUtils.copyProperties(paasFormEntityExt, formEntityGetVO);
            decisionInfoVO.setAppId(formGetDTO.getAppId());
            decisionInfoVO.setFormAttr(formEntityGetVO);
            decisionInfoVO.setFormId(paasFormEntityExt.getId());
            decisionInfoVO.setExplainList(explainList);
            decisionInfoVO.setFormExplainId(paasFormExplainEntity.getId());

            // 国际化白名单
            CompanyConfigEntity entity = companyConfigModel.getByConfigAlias(CompanyConfigEnum.I18N_WHITE.getAlias(), PaasConstant.DEFAULT_DATA_CORPID);
            String value = CompanyConfigEnum.I18N_WHITE.getValue();
            if (Objects.nonNull(entity)) {
                value = entity.getConfigValue();
            }
            List<String> whiteList = JsonHelperUtil.parseArray(value, String.class);
            boolean flag = CollectionsUtil.isNotEmpty(whiteList) && whiteList.contains(corpid);
            decisionInfoVO.setMultiLang(flag);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasForm数据库查询出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return decisionInfoVO;
    }

    @Override
    public FormUpdateVO decisionInfoUpdate(FormDecisionInfoUpdateDTO decisionInfoUpdateDTO) throws XbbException {
        FormUpdateVO formUpdateVO = new FormUpdateVO();

        try {
            List<FieldAttrEntityForDecisionInfo> explainList = decisionInfoUpdateDTO.getExplainList();
            String corpid = decisionInfoUpdateDTO.getCorpid();
            if (CollectionUtils.isEmpty(explainList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.EXPLAIN_NOT_EMPTY);
            }
            PaasFormExplainEntity explainEntity = paasFormExplainModel.getByKey(decisionInfoUpdateDTO.getFormExplainId().intValue(), corpid);
            if (explainEntity == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
            // 校验explain规则
            FormUpdateDTO formUpdateDTO = new FormUpdateDTO();
            BeanUtil.copyProperties(decisionInfoUpdateDTO, formUpdateDTO);
            validateAttrRule(formUpdateDTO);

            PaasFormExplainEntity paasFormExplainEntity = new PaasFormExplainEntity();
            List<FieldAttrEntityForDecisionInfo> explains = new ArrayList<>();
            for (int i = 0; i < explainList.size(); i++) {
                FieldAttrEntityForDecisionInfo fieldAttrEntity = explainList.get(i);
                fieldAttrEntity.setSort(i);

                explains.add(fieldAttrEntity);
            }

            paasFormExplainEntity.setExplains(JSONArray.toJSONString(explains));
            paasFormExplainEntity.setCorpid(corpid);
            paasFormExplainEntity.setId(formUpdateDTO.getFormExplainId());

            paasFormExplainModel.update(paasFormExplainEntity);
            paasFormExplainEntity.setDistributorMark(explainEntity.getDistributorMark());
            OperateModuleTypeEnum operateModuleType = OperateModuleTypeEnum.PAAS_FORM_EXPLAIN;
            JSONObject oldObj = JSONObject.parseObject(JSONObject.toJSONString(explainEntity));
            JSONObject newObj = JSONObject.parseObject(JSONObject.toJSONString(paasFormExplainEntity));


            // 记录日志
            List<DetailLogPojo> detailArr = logHelp.getDetailArr4Normal(corpid, operateModuleType, oldObj, newObj);
            if (detailArr != null) {
                String userId = formUpdateDTO.getUserId();
                String userName = formUpdateDTO.getLoginUserName();
                String formName = XbbRefTypeEnum.PROJECT_DECISION_INFO.getName();
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_UPDATE_FORM_EXPLAIN), userName, formName);
                String opObjectName = formName + I18nMessageUtil.getMessage(I18nStringConstant.FIELD_EXPLAIN);
                mongoLogHelp.buildLog4DetailArr(detailArr, corpid, userId, userName, operateModuleType, OperateTypeEnum.EDIT, paasFormExplainEntity.getId().toString(), opObjectName, memo, formUpdateDTO.getHttpHeader());
            }
        } catch (XbbException e) {
            LOG.error("更新项目决策信息失败", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }


        formUpdateVO.setAppId(decisionInfoUpdateDTO.getAppId());
        formUpdateVO.setFormId(decisionInfoUpdateDTO.getFormId());
        return formUpdateVO;
    }

    private void linkProductRelyHandel(FormGetDTO formGetDTO, String corpid, List<FieldAttrEntity> explainList) throws InstantiationException, IllegalAccessException, XbbException {
        List<LinkProductRelyEntity> productRelyEntityList = linkProductRelyModel.getByFormId(corpid, formGetDTO.getFormId(), DelEnum.NORMAL.getDel());
        if (CollectionsUtil.isNotEmpty(productRelyEntityList)) {
            Map<String, List<LinkProductRelyEntity>> linkProductRelyEntityMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            List<LinkProductRelyEntity> relyEntityList;
            for (LinkProductRelyEntity linkProductRelyEntity : productRelyEntityList) {
                relyEntityList = linkProductRelyEntityMap.getOrDefault(linkProductRelyEntity.getField(), new ArrayList<>());
                relyEntityList.add(linkProductRelyEntity);
                linkProductRelyEntityMap.put(linkProductRelyEntity.getField(), relyEntityList);
            }
            for (FieldAttrEntity fieldAttrEntity : explainList) {
                if (linkProductRelyEntityMap.containsKey(fieldAttrEntity.getAttr())) {
                    List<RelyPoJo> relyPoJoList = new ArrayList<>();
                    List<LinkProductRelyEntity> linkProductRelyEntityList = linkProductRelyEntityMap.get(fieldAttrEntity.getAttr());
                    for (LinkProductRelyEntity linkProductRelyEntity : linkProductRelyEntityList) {
                        // 联动表单的模板名称可能更改了，需要动态获取
                        if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), linkProductRelyEntity.getSourceBusinessType())) {
                            WorkOrderFormEntityExt workOrderFormEntityExt = workOrderFormModel.getByKey(linkProductRelyEntity.getSourceFormId(), linkProductRelyEntity.getCorpid());
                            linkProductRelyEntity.setTitle(workOrderFormEntityExt.getName());
                        }else {
                            PaasFormEntityExt paasFormEntityExt = paasFormModel.getByKey(linkProductRelyEntity.getSourceFormId(), linkProductRelyEntity.getCorpid());
                            linkProductRelyEntity.setTitle(paasFormEntityExt.getName());
                        }
                    }
                    BeanUtil.copyPropertiesList(linkProductRelyEntityList, relyPoJoList, RelyPoJo.class, false);
                    fieldAttrEntity.setRelyList(relyPoJoList);
                }
            }
        }
    }

    /**
     * 公司配置开关
     *
     * @param formEntityGetVO 表单实体
     * @param saasMark saas标识
     */
    private void formatCompanySetSwitchs(FormEntityGetVO formEntityGetVO, Integer saasMark) {
        if (!SaasMarkEnum.SAAS.getCode().equals(saasMark)) {
            return;
        }
        List<SwitchsPojo> switchs = formEntityGetVO.getSwitchs() != null ? formEntityGetVO.getSwitchs() : new ArrayList<>();
        Integer businessType = XbbRefTypeEnum.transferBusinessType4Distributor(formEntityGetVO.getBusinessType(), formEntityGetVO.getDistributorMark());
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        String corpid = formEntityGetVO.getCorpid();
        Long formId = formEntityGetVO.getId();
        List<CompanyConfigEnum> companyConfigEnumList = CompanyConfigEnum.getByBusinessType(businessType);
        if (companyConfigEnumList.isEmpty()) {
            return;
        }
        List<String> configAliasList = new ArrayList<>();
        companyConfigEnumList.forEach(companyConfigEnum -> configAliasList.add(companyConfigEnum.getAlias()));
        Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put(ParameterConstant.CORPID, corpid);
        map.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        map.put("configAliasIn", configAliasList);
        List<CompanyConfigEntity> companyConfigEntityList = companyConfigModel.findEntitys(map);
        List<String> companyExistAlias = new ArrayList<>();
        SwitchsPojo switchsPojo;
        SwitcherPojo switcher;
        for (CompanyConfigEntity companyConfigEntity : companyConfigEntityList) {
            companyExistAlias.add(companyConfigEntity.getConfigAlias());
            switchsPojo = new SwitchsPojo();
            CompanyConfigEnum companyConfigEnum = CompanyConfigEnum.getByAlias(companyConfigEntity.getConfigAlias());
            switcher = new SwitcherPojo(companyConfigEntity.getConfigAlias(), companyConfigEnum.getName(), companyConfigEntity.getConfigValue(), companyConfigEntity.getId());
            switchsPojo.setValue(Collections.singletonList(switcher));
            CompanyConfigDescribeEnum companyConfigDescribeEnumByAlias = CompanyConfigDescribeEnum.getCompanyConfigDescribeEnumByAlias(companyConfigEntity.getConfigAlias());
            switchsPojo.setTips(companyConfigDescribeEnumByAlias.getTips());
            switchsPojo.setTitle(companyConfigDescribeEnumByAlias.getTitle());
            // type为1为公司级配置
            switchsPojo.setType(1);
            switchsPojo.setSign(1);
            switchs.add(switchsPojo);
        }
        configAliasList.removeAll(companyExistAlias);
        for (String notInDbConfig : configAliasList) {
            switchsPojo = new SwitchsPojo();
            CompanyConfigEnum companyConfigEnum = CompanyConfigEnum.getByAlias(notInDbConfig);
            switcher = new SwitcherPojo(companyConfigEnum.getAlias(), companyConfigEnum.getName(), companyConfigEnum.getValue(), null);
            switchsPojo.setValue(Collections.singletonList(switcher));
            CompanyConfigDescribeEnum companyConfigDescribeEnumByAlias = CompanyConfigDescribeEnum.getCompanyConfigDescribeEnumByAlias(notInDbConfig);
            switchsPojo.setTips(companyConfigDescribeEnumByAlias.getTips());
            switchsPojo.setTitle(companyConfigDescribeEnumByAlias.getTitle());
            // type为1为公司级配置
            switchsPojo.setType(1);
            switchs.add(switchsPojo);
        }
        formEntityGetVO.setSwitchs(switchs);
    }

    /**
     * Description: 格式化处理表单设置开关
     * @param formEntityGetVO
     * @return void
     * @author 魏荣杰
     * @date 2019/5/24 16:59
     * @since v1.0
     */
    private void formatFormSetSwitchs(FormEntityGetVO formEntityGetVO) {
        List<SwitchsPojo> switchs = formEntityGetVO.getSwitchs() != null ? formEntityGetVO.getSwitchs() : new ArrayList<>();
        Integer businessType = XbbRefTypeEnum.transferBusinessType4Distributor(formEntityGetVO.getBusinessType(), formEntityGetVO.getDistributorMark());
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        String corpid = formEntityGetVO.getCorpid();
        Long formId = formEntityGetVO.getId();

        Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put(ParameterConstant.CORPID, corpid);
        map.put(StringConstant.BUSINESS_TYPE, businessType);
        map.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        map.put(ParameterConstant.FORMID, formId);
        List<FormConfigEntity> formConfigEntities = formConfigModel.findEntitys(map);
        switch (xbbRefTypeEnum) {
            case CONTRACT:
                formatFormSetContractSwitchs(switchs, formConfigEntities);
                break;
            case PURCHASE:
                formatFormSetPurchaseSwitchs(switchs, formConfigEntities);
                break;
            case OUTSTOCK:
            case CONTRACT_OUTSTOCK:
            case RETURNED_PURCHASE_OUTSTOCK:
            case OTHER_OUTSTOCK:
            case PRODUCTION_MATERIEL_OUTSTOCK:
            case WORK_ORDER_OUTSTOCK:
                formatFormSetOutstockSwitchs(switchs, formConfigEntities);
                break;
//            case CONTRACT_OUTSTOCK:
//                formatFormSetContractOutstockSwitchs(switchs, formConfigEntities);
//                break;
            case ORDER_OUTSTOCK:
                formatFormSetOrderOutstockSwitchs(switchs, formConfigEntities);
                break;
            case PRODUCTION_ORDER:
                formatFormSetProductionOrderSwitchs(switchs, formConfigEntities);
                break;
            case CUSTOMER_COMMUNICATE:
                formatFormSetCustomerCommunicate(switchs, formConfigEntities);
                break;
            case CUSTOMER_MANAGEMENT:
                formatFormSetCustomerSwitchs(switchs, formConfigEntities);
                break;
            case SALES_OPPORTUNITY:
                formatFormSetSalesOpportunitySwitchs(switchs, formConfigEntities);
                break;
            case CLUE:
                formatFormSetClueSwitchs(switchs, formConfigEntities);
                break;
            default:
                break;
        }
        formEntityGetVO.setSwitchs(switchs);
    }



    /**
     * Description: 格式化合同表单设置的特殊开关
     * @param switchs
     * @param formConfigEntities
     * @return void
     * @author 魏荣杰
     * @date 2019/5/27 9:18
     * @since v1.0
     */
    private void formatFormSetContractSwitchs(List<SwitchsPojo> switchs, List<FormConfigEntity> formConfigEntities) {

        SwitchsPojo paymentPlanSwitchs = new SwitchsPojo();
        SwitchsPojo superOutgoingWarehouseSwitchs = new SwitchsPojo();
        SwitchsPojo fieldPermissionsPlanSwitchs = new SwitchsPojo();
        List<FormConfigEntity> paymentPlanConfig = new ArrayList<>();
        List<FormConfigEntity> outgoingWarehouseConfig = new ArrayList<>();
        //字段权限
        List<FormConfigEntity> ownerConfig = new ArrayList<>();
        List<FormConfigEntity> coUserConfig = new ArrayList<>();
        List<FormConfigEntity> creatorConfig = new ArrayList<>();
        List<FormConfigEntity> authorizationRoleConfig = new ArrayList<>();

       List<SwitcherPojo> valueUser = new ArrayList<>();
        SwitcherPojo authorizationRoleSwitchs;
        for (FormConfigEntity entity : formConfigEntities) {
            String entityConfig = entity.getConfig();
            if (Objects.equals(entityConfig, FormConfigEnum.CONTRACT_AMOUNT_EQUAL_REPAYMENT_PLAN.getConfig())) {
                paymentPlanConfig.add(entity);
            } else if (Objects.equals(entityConfig, FormConfigEnum.CONTRACT_ALLOW_OUTSTOCK_PRODUCT_NUM_LARGER_SOLD.getConfig())) {
                outgoingWarehouseConfig.add(entity);
            } else if (Objects.equals(entityConfig, FormConfigEnum.CONTRACT_EDITABLE_PERMISSIONS_OWNER.getConfig())) {
                ownerConfig.add(entity);
            } else if (Objects.equals(entityConfig, FormConfigEnum.CONTRACT_EDITABLE_PERMISSIONS_CO_USER.getConfig())) {
                coUserConfig.add(entity);
            } else if (Objects.equals(entityConfig, FormConfigEnum.CONTRACT_EDITABLE_PERMISSIONS_CREATOR.getConfig())) {
                creatorConfig.add(entity);
            } else if (Objects.equals(entityConfig, FormConfigEnum.CONTRACT_SCREENING_AUTHORIZATION_ROLE.getConfig())) {
                authorizationRoleConfig.add(entity);
            }
        }
        //关联回款限制
        paymentPlanSwitchs.setTitle(I18nMessageUtil.getMessage(FormConfigConstant.CONTRACT_AMOUNT_EQUAL_REPAYMENT_PLAN_TITLE));
        paymentPlanSwitchs.setTips(FormConfigConstant.CONTRACT_AMOUNT_EQUAL_REPAYMENT_PLAN_TIPS);
        SwitcherPojo switcher;
        if (paymentPlanConfig.size() > 0) {
            FormConfigEntity formConfigEntity = paymentPlanConfig.get(0);
            FormConfigEnum formConfigEnum = FormConfigEnum.getByConfig(formConfigEntity.getConfig());
            switcher = new SwitcherPojo(formConfigEnum.getConfig(), formConfigEnum.getName(), formConfigEntity.getConfigValue(), formConfigEntity.getId());
        } else {
            FormConfigEnum formConfigEnum = FormConfigEnum.CONTRACT_AMOUNT_EQUAL_REPAYMENT_PLAN;
            switcher = new SwitcherPojo(formConfigEnum.getConfig(), formConfigEnum.getName(), formConfigEnum.getConfigValue(), 0L);
        }
        paymentPlanSwitchs.setValue(Collections.singletonList(switcher));
        //超发出库
        superOutgoingWarehouseSwitchs.setTitle(I18nMessageUtil.getMessage(FormConfigConstant.CONTRACT_ALLOW_OUTSTOCK_PRODUCT_NUM_LARGER_SOLD_TITLE));
        superOutgoingWarehouseSwitchs.setTips(FormConfigConstant.CONTRACT_ALLOW_OUTSTOCK_PRODUCT_NUM_LARGER_SOLD_TIPS);
        if (outgoingWarehouseConfig.size() > 0) {
            FormConfigEntity formConfigEntity = outgoingWarehouseConfig.get(0);
            FormConfigEnum formConfigEnum = FormConfigEnum.getByConfig(formConfigEntity.getConfig());
            switcher = new SwitcherPojo(formConfigEnum.getConfig(), formConfigEnum.getName(), formConfigEntity.getConfigValue(), formConfigEntity.getId());
        } else {
            FormConfigEnum formConfigEnum = FormConfigEnum.CONTRACT_ALLOW_OUTSTOCK_PRODUCT_NUM_LARGER_SOLD;
            switcher = new SwitcherPojo(formConfigEnum.getConfig(), formConfigEnum.getName(), formConfigEnum.getConfigValue(), 0L);
        }
        superOutgoingWarehouseSwitchs.setValue(Collections.singletonList(switcher));
        //字段权限
        fieldPermissionsPlanSwitchs.setTitle(I18nMessageUtil.getMessage(FormConfigConstant.CONTRACT_OWNER_COUSER_CREATOR_AUTHORIZATION_ROLE_TITLE));
        fieldPermissionsPlanSwitchs.setTips(FormConfigConstant.CONTRACT_OWNER_COUSER_CREATOR_AUTHORIZATION_ROLE_TIPS);
        //负责人
        if (ownerConfig.size() > 0) {
            FormConfigEntity formConfigEntity = ownerConfig.get(0);
            FormConfigEnum formConfigEnum = FormConfigEnum.getByConfig(formConfigEntity.getConfig());
            switcher = new SwitcherPojo(formConfigEnum.getConfig(), formConfigEnum.getName(), formConfigEntity.getConfigValue(), formConfigEntity.getId());
        } else {
            FormConfigEnum formConfigEnum = FormConfigEnum.CONTRACT_EDITABLE_PERMISSIONS_OWNER;
            switcher = new SwitcherPojo(formConfigEnum.getConfig(), formConfigEnum.getName(), formConfigEnum.getConfigValue(), -1L);
        }
        valueUser.add(switcher);
        //协同人
        if (coUserConfig.size() > 0) {
            FormConfigEntity formConfigEntity = coUserConfig.get(0);
            FormConfigEnum formConfigEnum = FormConfigEnum.getByConfig(formConfigEntity.getConfig());
            switcher = new SwitcherPojo(formConfigEnum.getConfig(), formConfigEnum.getName(), formConfigEntity.getConfigValue(), formConfigEntity.getId());
        } else {
            FormConfigEnum formConfigEnum = FormConfigEnum.CONTRACT_EDITABLE_PERMISSIONS_CO_USER;
            switcher = new SwitcherPojo(formConfigEnum.getConfig(), formConfigEnum.getName(), formConfigEnum.getConfigValue(), -2L);
        }
        valueUser.add(switcher);
        //创建人
        if (creatorConfig.size() > 0) {
            FormConfigEntity formConfigEntity = creatorConfig.get(0);
            FormConfigEnum formConfigEnum = FormConfigEnum.getByConfig(formConfigEntity.getConfig());
            switcher = new SwitcherPojo(formConfigEnum.getConfig(), formConfigEnum.getName(), formConfigEntity.getConfigValue(), formConfigEntity.getId());
        } else {
            FormConfigEnum formConfigEnum = FormConfigEnum.CONTRACT_EDITABLE_PERMISSIONS_CREATOR;
            switcher = new SwitcherPojo(formConfigEnum.getConfig(), formConfigEnum.getName(), formConfigEnum.getConfigValue(), -3L);
        }
        valueUser.add(switcher);
        //授权角色筛选(也是字段权限里面的)
        if (authorizationRoleConfig.size() > 0) {
            FormConfigEntity formConfigEntity = authorizationRoleConfig.get(0);
            JSONObject jsonObject = new JSONObject();
            String configValue = formConfigEntity.getConfigValue();
            JSONObject jsonConfigValue = JSONObject.parseObject(configValue);
            List<Integer> list = new ArrayList<>();
            String configRole = jsonConfigValue.getString("role");
            if (StringUtils.isNotEmpty(configRole)) {
                configRole = configRole.substring(1, configRole.length()-1) ;
                String[] split = configRole.split(",");
                if (split != null && split.length > 0) {
                    for (int i = 0; i < split.length; i++) {
                        if (StringUtils.isNotEmpty(split[i])) {
                            list.add(Integer.valueOf(split[i]));
                        }
                    }
                    jsonObject.put("role", list);
                }
            } else {
                jsonObject.put("role", list);
            }
            authorizationRoleSwitchs = new SwitcherPojo();
            authorizationRoleSwitchs.setConfig(formConfigEntity.getConfig());
            authorizationRoleSwitchs.setJsonValue(jsonObject);
            fieldPermissionsPlanSwitchs.setSwitcherRole(authorizationRoleSwitchs);
        } else {
            FormConfigEnum formConfigEnum = FormConfigEnum.CONTRACT_SCREENING_AUTHORIZATION_ROLE;
            String configValue = formConfigEnum.getConfigValue();
            JSONObject jsonObject = JSONObject.parseObject(configValue);
            String configRole = jsonObject.getString("role");
            List<Integer> role = new ArrayList<>();
            if (StringUtil.isNotEmpty(configRole)) {
                configRole = configRole.substring(1, configRole.length() - 1);
                String[] split = configRole.split(",");
                for (int i = 0; i < split.length; i++) {
                    role.add(Integer.valueOf(split[i]));
                }
            }
            JSONObject roleJson = new JSONObject();
            roleJson.put("role", role);
            authorizationRoleSwitchs = new SwitcherPojo();
            authorizationRoleSwitchs.setConfig(formConfigEnum.getConfig());
            authorizationRoleSwitchs.setJsonValue(roleJson);
            fieldPermissionsPlanSwitchs.setSwitcherRole(authorizationRoleSwitchs);
        }
        fieldPermissionsPlanSwitchs.setValue(valueUser);
        fieldPermissionsPlanSwitchs.setType(2);
        switchs.add(fieldPermissionsPlanSwitchs);
        switchs.add(paymentPlanSwitchs);
        switchs.add(superOutgoingWarehouseSwitchs);
    }

    /**
     * Description: 格式化采购合同表单设置的特殊开关
     * @param switchs
     * @param formConfigEntities
     * @author 魏荣杰
     * @date 2019/5/24 20:54
     * @since v1.0
     */
    private void formatFormSetPurchaseSwitchs(List<SwitchsPojo> switchs, List<FormConfigEntity> formConfigEntities) {
        SwitchsPojo productSwitch = new SwitchsPojo();
        SwitchsPojo paymentPlanSwitch = new SwitchsPojo();
        List<FormConfigEntity> productConfig = new ArrayList<>();
        List<FormConfigEntity> paymentPlanConfig = new ArrayList<>();
        for (FormConfigEntity entity : formConfigEntities) {
            if (Objects.equals(entity.getConfig(), FormConfigEnum.PURCHASE_PRODUCT_MUST_BELONG_SUPPLIER.getConfig())) {
                productConfig.add(entity);
            }
            if (Objects.equals(entity.getConfig(), FormConfigEnum.PURCHASE_AMOUNT_EQUAL_PAYMENT_PLAN.getConfig())) {
                paymentPlanConfig.add(entity);
            }
        }
        productSwitch.setTitle(I18nMessageUtil.getMessage(FormConfigConstant.PURCHASE_PRODUCT_MUST_BELONG_SUPPLIER_TITLE));
        productSwitch.setTips(FormConfigConstant.PURCHASE_PRODUCT_MUST_BELONG_SUPPLIER_TIPS);
        if (productConfig.size() > 0) {
            FormConfigEntity formConfigEntity = productConfig.get(0);
            FormConfigEnum formConfigEnum = FormConfigEnum.getByConfig(formConfigEntity.getConfig());
            SwitcherPojo switcher = new SwitcherPojo(formConfigEnum.getConfig(), formConfigEnum.getName(), formConfigEntity.getConfigValue(), formConfigEntity.getId());
            productSwitch.setValue(Collections.singletonList(switcher));
        } else {
            FormConfigEnum formConfigEnum = FormConfigEnum.PURCHASE_PRODUCT_MUST_BELONG_SUPPLIER;
            SwitcherPojo switcher = new SwitcherPojo(formConfigEnum.getConfig(), formConfigEnum.getName(), formConfigEnum.getConfigValue(), 0L);
            productSwitch.setValue(Collections.singletonList(switcher));
        }

        paymentPlanSwitch.setTitle(I18nMessageUtil.getMessage(FormConfigConstant.PURCHASE_AMOUNT_EQUAL_PAYMENT_PLAN_TITLE));
        paymentPlanSwitch.setTips(FormConfigConstant.PURCHASE_AMOUNT_EQUAL_PAYMENT_PLAN_TIPS);
        if (paymentPlanConfig.size() > 0) {
            FormConfigEntity formConfigEntity = paymentPlanConfig.get(0);
            FormConfigEnum formConfigEnum= FormConfigEnum.getByConfig(formConfigEntity.getConfig());
            SwitcherPojo switcher = new SwitcherPojo(formConfigEnum.getConfig(), formConfigEnum.getName(), formConfigEntity.getConfigValue(), formConfigEntity.getId());
            paymentPlanSwitch.setValue(Collections.singletonList(switcher));
        } else {
            FormConfigEnum formConfigEnum = FormConfigEnum.PURCHASE_AMOUNT_EQUAL_PAYMENT_PLAN;
            SwitcherPojo switcher = new SwitcherPojo(formConfigEnum.getConfig(), formConfigEnum.getName(), formConfigEnum.getConfigValue(), 0L);
            paymentPlanSwitch.setValue(Collections.singletonList(switcher));
        }
        switchs.add(productSwitch);
        switchs.add(paymentPlanSwitch);
    }

    /**
     * Description: 格式化出库单表单设置的特殊开关
     * @param switchs
     * @param formConfigEntities
     * @author 魏荣杰
     * @date 2019/5/27 9:50
     * @since v1.0
     */
    private void formatFormSetOutstockSwitchs(List<SwitchsPojo> switchs, List<FormConfigEntity> formConfigEntities) {
        //负库存和合同售价关联 至此已全部弃用，无需再表单设计页展示
     /*   SwitchsPojo outgoingSwitch = new SwitchsPojo();
        SwitchsPojo salePriceSwitch = new SwitchsPojo();
        List<FormConfigEntity> outgoingConfig = new ArrayList<>();
        List<FormConfigEntity> salePriceConfig = new ArrayList<>();
        for (FormConfigEntity entity : formConfigEntities) {
            if (Objects.equals(entity.getConfig(), FormConfigEnum.OUTSTOCK_INSUFFICIENT_NOT_ALLOW_WAREHOUSING.getConfig())) {
                outgoingConfig.add(entity);
            }
            if (Objects.equals(entity.getConfig(), FormConfigEnum.OUTSTOCK_DISPLAY_SALE_PRICE.getConfig())) {
                salePriceConfig.add(entity);
            }
        }
        outgoingSwitch.setTitle(I18nMessageUtil.getMessage(FormConfigConstant.OUTSTOCK_INSUFFICIENT_NOT_ALLOW_WAREHOUSING_TITLE));
        outgoingSwitch.setTips(I18nMessageUtil.getMessage(FormConfigConstant.OUTSTOCK_INSUFFICIENT_NOT_ALLOW_WAREHOUSING_TIPS));
        if (outgoingConfig.size() > 0) {
            FormConfigEntity formConfigEntity = outgoingConfig.get(0);
            FormConfigEnum formConfigEnum = FormConfigEnum.getByConfig(formConfigEntity.getConfig());
            SwitcherPojo switcher = new SwitcherPojo(formConfigEnum.getConfig(), formConfigEnum.getName(), formConfigEntity.getConfigValue(), formConfigEntity.getId());
            outgoingSwitch.setValue(Collections.singletonList(switcher));
        } else {
            FormConfigEnum formConfigEnum = FormConfigEnum.OUTSTOCK_INSUFFICIENT_NOT_ALLOW_WAREHOUSING;
            SwitcherPojo switcher = new SwitcherPojo(formConfigEnum.getConfig(), formConfigEnum.getName(), formConfigEnum.getConfigValue(), 0L);
            outgoingSwitch.setValue(Collections.singletonList(switcher));
        }

        salePriceSwitch.setTitle(I18nMessageUtil.getMessage(FormConfigConstant.OUTSTOCK_DISPLAY_SALE_PRICE_TITLE));
        salePriceSwitch.setTips(I18nMessageUtil.getMessage(FormConfigConstant.OUTSTOCK_DISPLAY_SALE_PRICE_TIPS));
        if (salePriceConfig.size() > 0) {
            FormConfigEntity formConfigEntity = salePriceConfig.get(0);
            FormConfigEnum formConfigEnum= FormConfigEnum.getByConfig(formConfigEntity.getConfig());
            SwitcherPojo switcher = new SwitcherPojo(formConfigEnum.getConfig(), formConfigEnum.getName(), formConfigEntity.getConfigValue(), formConfigEntity.getId());
            salePriceSwitch.setValue(Collections.singletonList(switcher));
        } else {
            FormConfigEnum formConfigEnum = FormConfigEnum.OUTSTOCK_DISPLAY_SALE_PRICE;
            SwitcherPojo switcher = new SwitcherPojo(formConfigEnum.getConfig(), formConfigEnum.getName(), formConfigEnum.getConfigValue(), 0L);
            salePriceSwitch.setValue(Collections.singletonList(switcher));
        }
//        switchs.add(outgoingSwitch);
        switchs.add(salePriceSwitch);*/
    }

    /**
     * Description: 格式化出库发货单表单设置的特殊开关
     * @param switchs
     * @param formConfigEntities
     * @author 魏荣杰
     * @date 2019/5/27 9:50
     * @since v1.0
     */
    private void formatFormSetOrderOutstockSwitchs(List<SwitchsPojo> switchs, List<FormConfigEntity> formConfigEntities){
        SwitchsPojo switchsPojo = new SwitchsPojo();
        switchsPojo.setTitle(I18nMessageUtil.getMessage(FormConfigConstant.ENABLE_SHIPPING_PROCESS_TITLE_DISTRIBUTOR));
        switchsPojo.setTips(I18nMessageUtil.getMessage(FormConfigConstant.ENABLE_SHIPPING_PROCESS_TIPS_DISTRIBUTOR));
        List<SwitcherPojo> switcherPojos = new ArrayList<>();
        SwitcherPojo switcherPojo = null;
        for (FormConfigEntity entity : formConfigEntities) {
            if (Objects.equals(entity.getConfig(), FormConfigEnum.ENABLE_SHIPPING_PROCESS.getConfig())) {
                switcherPojo = new SwitcherPojo(FormConfigEnum.ENABLE_SHIPPING_PROCESS.getConfig(), FormConfigEnum.ENABLE_SHIPPING_PROCESS.getName(), entity.getConfigValue(), entity.getId());
                //如果经销商管理应用开启之后，出库发货单发货单设置项勾选且置灰
                // 判断经销商管理应用是否启用
                boolean distributorIsOpen = false;
                boolean electronicFaceSheetIsOpen = false;
                try {
                    distributorIsOpen = paasAppService.validateAppEnable(null, XbbRefTypeEnum.DISTRIBUTOR.getAlias(), Integer.valueOf(1),entity.getCorpid());
                    //如果电子面单应用关闭，出库发货单，表单模板设计界面【启用发货流程管理】按钮应该隐藏
                    // 获取公司级配置
                    List<String> aliasList = Arrays.asList(CompanyConfigEnum.PRICE_MANAGE.getAlias(), CompanyConfigEnum.LOGISTICS_TRACKING.getAlias(), CompanyConfigEnum.ELECTRONIC_FACE_SHEET.getAlias());
                    Map<String,String> companyConfigMap = companyConfigModel.getConfigValueMap(entity.getCorpid(),aliasList);
                    if (Objects.nonNull(companyConfigMap) && Objects.equals(companyConfigMap.get(CompanyConfigEnum.ELECTRONIC_FACE_SHEET.getAlias()),"1")){
                        electronicFaceSheetIsOpen = true;
                    }
                    if (!electronicFaceSheetIsOpen){
                        return;
                    }
                } catch (XbbException e) {
                    e.printStackTrace();
                }
                if (distributorIsOpen){
                    switcherPojo.setForbidden(1);
                    switcherPojo.setValue("1");
                }
            }
        }
        if (Objects.isNull(switcherPojo)) {
            switcherPojo = new SwitcherPojo(FormConfigEnum.ENABLE_SHIPPING_PROCESS.getConfig(), FormConfigEnum.ENABLE_SHIPPING_PROCESS.getName(), FormConfigEnum.ENABLE_SHIPPING_PROCESS.getConfigValue(), 0L);
        }
        switcherPojos.add(switcherPojo);
        switchsPojo.setValue(switcherPojos);
        switchs.add(switchsPojo);
    }

//    /**
//     * Description: 格式化销售出库单表单设置的特殊开关
//     * @param switchs
//     * @param formConfigEntities
//     * @author 魏荣杰
//     * @date 2019/5/27 9:50
//     * @since v1.0
//     */
//    private void formatFormSetContractOutstockSwitchs(List<SwitchsPojo> switchs, List<FormConfigEntity> formConfigEntities){
//        SwitchsPojo switchsPojo = new SwitchsPojo();
//        switchsPojo.setTitle(I18nMessageUtil.getMessage(FormConfigConstant.ENABLE_SHIPPING_PROCESS_TITLE));
//        switchsPojo.setTips(I18nMessageUtil.getMessage(FormConfigConstant.ENABLE_SHIPPING_PROCESS_TIPS));
//        List<SwitcherPojo> switcherPojos = new ArrayList<>();
//        SwitcherPojo switcherPojo = null;
//        for (FormConfigEntity entity : formConfigEntities) {
//            if (Objects.equals(entity.getConfig(), FormConfigEnum.ENABLE_SHIPPING_PROCESS.getConfig())) {
//                switcherPojo = new SwitcherPojo(FormConfigEnum.ENABLE_SHIPPING_PROCESS.getConfig(), FormConfigEnum.ENABLE_SHIPPING_PROCESS.getName(), entity.getConfigValue(), entity.getId());
//                boolean electronicFaceSheetIsOpen = false;
//                //如果电子面单应用关闭，销售出库单，表单模板设计界面【启用发货流程管理】按钮应该隐藏
//                // 获取公司级配置
//                List<String> aliasList = Arrays.asList(CompanyConfigEnum.PRICE_MANAGE.getAlias(), CompanyConfigEnum.LOGISTICS_TRACKING.getAlias(), CompanyConfigEnum.ELECTRONIC_FACE_SHEET.getAlias());
//                Map<String,String> companyConfigMap = companyConfigModel.getConfigValueMap(entity.getCorpid(),aliasList);
//                if (Objects.nonNull(companyConfigMap) && Objects.equals(companyConfigMap.get(CompanyConfigEnum.ELECTRONIC_FACE_SHEET.getAlias()),"1")){
//                    electronicFaceSheetIsOpen = true;
//                }
//                if (!electronicFaceSheetIsOpen){
//                    return;
//                }
//            }
//        }
//        if (Objects.isNull(switcherPojo)) {
//            switcherPojo = new SwitcherPojo(FormConfigEnum.ENABLE_SHIPPING_PROCESS.getConfig(), FormConfigEnum.ENABLE_SHIPPING_PROCESS.getName(), FormConfigEnum.ENABLE_SHIPPING_PROCESS.getConfigValue(), 0L);
//        }
//        switcherPojos.add(switcherPojo);
//        switchsPojo.setValue(switcherPojos);
//        switchs.add(switchsPojo);
//    }

    /**
     * Description: 格式化生产单表单设置的特殊开关
     * @param switchs
     * @param formConfigEntities
     * @author 魏荣杰
     * @date 2019/5/27 9:50
     * @since v1.0
     */
    private void formatFormSetProductionOrderSwitchs(List<SwitchsPojo> switchs, List<FormConfigEntity> formConfigEntities) {
        SwitchsPojo switchsPojo = new SwitchsPojo();
        switchsPojo.setTitle(I18nMessageUtil.getMessage(FormConfigConstant.PRODUCTION_ORDER_WAIT_TITLE));
        switchsPojo.setTips(FormConfigConstant.PRODUCTION_ORDER_WAIT_TIPS);
        List<SwitcherPojo> switcherPojos = new ArrayList<>();
        SwitcherPojo switcherPojo1 = null;
        SwitcherPojo switcherPojo2 = null;
        for (FormConfigEntity entity : formConfigEntities) {
            if (Objects.equals(entity.getConfig(), FormConfigEnum.PRODUCTION_ORDER_AUTO_UPDATE_NEW_CONTRACT.getConfig())) {
                switcherPojo1 = new SwitcherPojo(FormConfigEnum.PRODUCTION_ORDER_AUTO_UPDATE_NEW_CONTRACT.getConfig(), FormConfigEnum.PRODUCTION_ORDER_AUTO_UPDATE_NEW_CONTRACT.getName(), entity.getConfigValue(), entity.getId());
            }
            if (Objects.equals(entity.getConfig(), FormConfigEnum.PRODUCTION_ORDER_AUTO_UPDATE_IMPORT_CONTRACT.getConfig())) {
                switcherPojo2 = new SwitcherPojo(FormConfigEnum.PRODUCTION_ORDER_AUTO_UPDATE_IMPORT_CONTRACT.getConfig(), FormConfigEnum.PRODUCTION_ORDER_AUTO_UPDATE_IMPORT_CONTRACT.getName(), entity.getConfigValue(), entity.getId());
            }
        }
        if (Objects.isNull(switcherPojo1)) {
            switcherPojo1 = new SwitcherPojo(FormConfigEnum.PRODUCTION_ORDER_AUTO_UPDATE_NEW_CONTRACT.getConfig(), FormConfigEnum.PRODUCTION_ORDER_AUTO_UPDATE_NEW_CONTRACT.getName(), FormConfigEnum.PRODUCTION_ORDER_AUTO_UPDATE_NEW_CONTRACT.getConfigValue(), 0L);
        }
        if (Objects.isNull(switcherPojo2)) {
            switcherPojo2 = new SwitcherPojo(FormConfigEnum.PRODUCTION_ORDER_AUTO_UPDATE_IMPORT_CONTRACT.getConfig(), FormConfigEnum.PRODUCTION_ORDER_AUTO_UPDATE_IMPORT_CONTRACT.getName(), FormConfigEnum.PRODUCTION_ORDER_AUTO_UPDATE_IMPORT_CONTRACT.getConfigValue(), 0L);
        }

        switcherPojos.add(switcherPojo1);
        switcherPojos.add(switcherPojo2);
        switchsPojo.setValue(switcherPojos);
        switchs.add(switchsPojo);
    }

    /**
     * 格式化CRM跟进记录表单设置的特殊开关
     * @param switchs 开关列表
     * @param formConfigEntities 表单配置实体
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-06-03 16:29
     * @since v1.0
     * @version v1.0
     */
    private void formatFormSetCustomerCommunicate(List<SwitchsPojo> switchs, List<FormConfigEntity> formConfigEntities) {
        SwitcherPojo autoAddSwitcherPojo = null;
        for(FormConfigEntity entity : formConfigEntities) {
            if(Objects.equals(entity.getConfig(), FormConfigEnum.CALL_AUTO_ADD_CUSTOMER_COMMUNICATE.getConfig())) {
                autoAddSwitcherPojo = new SwitcherPojo(FormConfigEnum.CALL_AUTO_ADD_CUSTOMER_COMMUNICATE.getConfig(), FormConfigEnum.CALL_AUTO_ADD_CUSTOMER_COMMUNICATE.getName(), entity.getConfigValue(), entity.getId());
                break;
            }
        }
        if(Objects.isNull(autoAddSwitcherPojo)) {
            autoAddSwitcherPojo = new SwitcherPojo(FormConfigEnum.CALL_AUTO_ADD_CUSTOMER_COMMUNICATE.getConfig(), FormConfigEnum.CALL_AUTO_ADD_CUSTOMER_COMMUNICATE.getName(), FormConfigEnum.CALL_AUTO_ADD_CUSTOMER_COMMUNICATE.getConfigValue(), 0L);
        }
        SwitchsPojo switchsPojo2 = new SwitchsPojo();
        switchsPojo2.setTitle(I18nMessageUtil.getMessage(FormConfigConstant.CALLED_AUTO_ADD_COMMUNICATE_TITLE));
        switchsPojo2.setTips(FormConfigConstant.CALLED_AUTO_ADD_COMMUNICATE_TIPS);
        List<SwitcherPojo> switcherPojos2 = new ArrayList<>();

        switcherPojos2.add(autoAddSwitcherPojo);
        switchsPojo2.setValue(switcherPojos2);
        switchs.add(switchsPojo2);
    }

    /**
     * 格式化CRM客户表单设置的特殊开关
     * @param switchs 开关列表
     * @param formConfigEntities 表单配置实体
     * @return
     * @throws
     * @author youli.chen
     * @date 2019-06-03 16:29
     * @since v1.0
     * @version v1.0
     */
    private void formatFormSetCustomerSwitchs(List<SwitchsPojo> switchs, List<FormConfigEntity> formConfigEntities) {
        SwitcherPojo autoAddSwitcherPojo = null;
        for(FormConfigEntity entity : formConfigEntities) {
            if(Objects.equals(entity.getConfig(), FormConfigEnum.CUSTOMER_LAST_CONNECT_TIME.getConfig())) {
                autoAddSwitcherPojo = new SwitcherPojo(FormConfigEnum.CUSTOMER_LAST_CONNECT_TIME.getConfig(), FormConfigEnum.CUSTOMER_LAST_CONNECT_TIME.getName(), entity.getConfigValue(), entity.getId());
                break;
            }
        }
        if(Objects.isNull(autoAddSwitcherPojo)) {
            autoAddSwitcherPojo = new SwitcherPojo(FormConfigEnum.CUSTOMER_LAST_CONNECT_TIME.getConfig(), FormConfigEnum.CUSTOMER_LAST_CONNECT_TIME.getName(), FormConfigEnum.CUSTOMER_LAST_CONNECT_TIME.getConfigValue(), 0L);
        }
        SwitchsPojo switchsPojo2 = new SwitchsPojo();
        switchsPojo2.setTitle(I18nMessageUtil.getMessage(FormConfigConstant.CUSTOMER_LAST_CONNECT_TIME_TITLE));
        switchsPojo2.setTips(FormConfigConstant.CUSTOMER_LAST_CONNECT_TIME_TIPS);
        switchsPojo2.setSign(0);
        List<SwitcherPojo> switcherPojos2 = new ArrayList<>();

        switcherPojos2.add(autoAddSwitcherPojo);
        switchsPojo2.setValue(switcherPojos2);
        switchs.add(switchsPojo2);
    }

    /**
     * 格式化CRM销售机会表单设置的特殊开关
     * @param switchs 开关列表
     * @param formConfigEntities 表单配置实体
     * @return
     * @throws
     * @author youli.chen
     * @date 2019-06-03 16:29
     * @since v1.0
     * @version v1.0
     */
    private void formatFormSetSalesOpportunitySwitchs(List<SwitchsPojo> switchs, List<FormConfigEntity> formConfigEntities) {
        SwitcherPojo autoAddSwitcherPojo = null;
        for(FormConfigEntity entity : formConfigEntities) {
            if(Objects.equals(entity.getConfig(), FormConfigEnum.SALES_OPPORTUNITY_LAST_CONNECT_TIME.getConfig())) {
                autoAddSwitcherPojo = new SwitcherPojo(FormConfigEnum.SALES_OPPORTUNITY_LAST_CONNECT_TIME.getConfig(), FormConfigEnum.SALES_OPPORTUNITY_LAST_CONNECT_TIME.getName(), entity.getConfigValue(), entity.getId());
                break;
            }
        }
        if(Objects.isNull(autoAddSwitcherPojo)) {
            autoAddSwitcherPojo = new SwitcherPojo(FormConfigEnum.SALES_OPPORTUNITY_LAST_CONNECT_TIME.getConfig(), FormConfigEnum.SALES_OPPORTUNITY_LAST_CONNECT_TIME.getName(), FormConfigEnum.SALES_OPPORTUNITY_LAST_CONNECT_TIME.getConfigValue(), 0L);
        }
        SwitchsPojo switchsPojo2 = new SwitchsPojo();
        switchsPojo2.setTitle(I18nMessageUtil.getMessage(FormConfigConstant.CUSTOMER_LAST_CONNECT_TIME_TITLE));
        switchsPojo2.setTips(FormConfigConstant.CUSTOMER_LAST_CONNECT_TIME_TIPS);
        List<SwitcherPojo> switcherPojos2 = new ArrayList<>();

        switcherPojos2.add(autoAddSwitcherPojo);
        switchsPojo2.setValue(switcherPojos2);
        switchs.add(switchsPojo2);
    }

    /**
     * 格式化线索表单设置的特殊开关
     * @param switchs 开关列表
     * @param formConfigEntities 表单配置实体
     * @return
     * @throws
     */
    private void formatFormSetClueSwitchs(List<SwitchsPojo> switchs, List<FormConfigEntity> formConfigEntities) {
        SwitcherPojo autoAddSwitcherPojo = null;
        for(FormConfigEntity entity : formConfigEntities) {
            if(Objects.equals(entity.getConfig(), FormConfigEnum.CLUE_LAST_CONNECT_TIME.getConfig())) {
                autoAddSwitcherPojo = new SwitcherPojo(FormConfigEnum.CLUE_LAST_CONNECT_TIME.getConfig(), FormConfigEnum.CLUE_LAST_CONNECT_TIME.getName(), entity.getConfigValue(), entity.getId());
                break;
            }
        }
        if(Objects.isNull(autoAddSwitcherPojo)) {
            autoAddSwitcherPojo = new SwitcherPojo(FormConfigEnum.CLUE_LAST_CONNECT_TIME.getConfig(), FormConfigEnum.CLUE_LAST_CONNECT_TIME.getName(), FormConfigEnum.SALES_OPPORTUNITY_LAST_CONNECT_TIME.getConfigValue(), 0L);
        }
        SwitchsPojo switchsPojo2 = new SwitchsPojo();
        switchsPojo2.setTitle(I18nMessageUtil.getMessage(FormConfigConstant.CUSTOMER_LAST_CONNECT_TIME_TITLE));
        switchsPojo2.setTips(FormConfigConstant.CUSTOMER_LAST_CONNECT_TIME_TIPS);
        List<SwitcherPojo> switcherPojos2 = new ArrayList<>();

        switcherPojos2.add(autoAddSwitcherPojo);
        switchsPojo2.setValue(switcherPojos2);
        switchs.add(switchsPojo2);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public FormUpdateVO update(FormUpdateDTO formUpdateDTO) throws XbbException {
        FormUpdateVO formUpdateVO = new FormUpdateVO();

        try {
            if (CollectionUtils.isEmpty(formUpdateDTO.getExplainList())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.EXPLAIN_NOT_EMPTY);
            }
            FormEntityUpdateDTO formEntityUpdateDTO = formUpdateDTO.getFormAttr();
            formUpdateDTO.setBusinessType(formEntityUpdateDTO.getBusinessType());
            // 校验explain规则
            validateAttrRule(formUpdateDTO);
            PaasFormEntity paasFormEntity = new PaasFormEntity();
            BeanUtils.copyProperties(formEntityUpdateDTO, paasFormEntity);
            paasFormEntity.setId(formUpdateDTO.getFormId());
            paasFormEntity.setCorpid(formUpdateDTO.getCorpid());
            // 这里不改表单名称
            paasFormEntity.setName(null);
            // 摘要和协同人权限需要转成String
            paasFormEntity.setSummary(JSONArray.toJSONString(formEntityUpdateDTO.getSummary()));
            paasFormEntity.setLabels(JSONArray.toJSONString(formEntityUpdateDTO.getLabels()));
            paasFormEntity.setCustomTitle(JSONArray.toJSONString(formEntityUpdateDTO.getCustomTitle()));
            paasFormEntity.setSurcharge(JSONArray.toJSONString(formEntityUpdateDTO.getSurcharge()));
            String corpid = formUpdateDTO.getCorpid();
            String userId = formUpdateDTO.getUserId();
            String userName = formUpdateDTO.getLoginUserName();
            List<SwitchsPojo> switches = formEntityUpdateDTO.getSwitchs();
            if (CollectionsUtil.isNotEmpty(switches)) {
                List<SwitchsPojo> fieldSwitches = new ArrayList<>();
                switches.forEach(switchesPojo -> {
                    if (Objects.equals(switchesPojo.getTitle(), I18nMessageUtil.getMessage(FormConfigConstant.CONTRACT_OWNER_COUSER_CREATOR_AUTHORIZATION_ROLE_TITLE))) {
                        fieldSwitches.add(switchesPojo);
                    }
                });

                if (!fieldSwitches.isEmpty()) {
                    SwitcherPojo switcherPojo = new SwitcherPojo();
                    for (SwitchsPojo fieldSwitch : fieldSwitches) {
                        JSONObject jsonValue = fieldSwitch.getSwitcherRole().getJsonValue();
                        switcherPojo.setValue(jsonValue.toString().replaceAll("\"(\\w+)\"(\\s*:\\s*)", "$1$2"));
                        switcherPojo.setConfig(fieldSwitch.getSwitcherRole().getConfig());

                        FormConfigAddBatchDTO formEditConfigAddBatchDTO = new FormConfigAddBatchDTO();
                        List<FormConfigAddDTO> configAddDTOList = new ArrayList<>();
                        FormConfigAddDTO formConfigAddDTO = new FormConfigAddDTO();
                        formConfigAddDTO.setConfigValue(switcherPojo.getValue());
                        formConfigAddDTO.setConfig(switcherPojo.getConfig());
                        configAddDTOList.add(formConfigAddDTO);

                        BeanUtil.copyProperties(formUpdateDTO, formEditConfigAddBatchDTO);
                        formEditConfigAddBatchDTO.setFormConfigList(configAddDTOList);
                        formEditConfigAddBatchDTO.setSaasMark(paasFormEntity.getSaasMark());
                        formEditConfigAddBatchDTO.setBusinessType(paasFormEntity.getBusinessType());
                        formConfigService.saveBatch(formEditConfigAddBatchDTO);
                    }
                }
            }
            if (Objects.nonNull(switches)) {
                List<SwitchsPojo> fieldValueSwitches = new ArrayList<>();
                List<SwitchsPojo> formSwitches = new ArrayList<>();
                List<SwitchsPojo> companySwitches = new ArrayList<>();
                switches.forEach(switchesPojo -> {
                    if (Objects.equals(switchesPojo.getType(), 0)) {
                        formSwitches.add(switchesPojo);
                    }
                    if (Objects.equals(switchesPojo.getType(), 1)) {
                        companySwitches.add(switchesPojo);
                    }
                    if (Objects.equals(switchesPojo.getTitle(), I18nMessageUtil.getMessage(FormConfigConstant.CONTRACT_OWNER_COUSER_CREATOR_AUTHORIZATION_ROLE_TITLE))) {
                        fieldValueSwitches.add(switchesPojo);
                    }
                });
                if (!companySwitches.isEmpty()) {
                    CompanyConfigAddBatchDTO companyConfigAddBatchDTO = new CompanyConfigAddBatchDTO();
                    List<CompanyConfigAddDTO> configAddDTOList = new ArrayList<>();
                    CompanyConfigAddDTO companyConfigAddDTO;
                    for (SwitchsPojo switchsPojo : companySwitches) {
                        for (SwitcherPojo switcherPojo : switchsPojo.getValue()) {
                            companyConfigAddDTO = new CompanyConfigAddDTO();
                            companyConfigAddDTO.setConfigAlias(switcherPojo.getConfig());
                            companyConfigAddDTO.setConfigName(switcherPojo.getName());
                            companyConfigAddDTO.setConfigValue(switcherPojo.getValue());
                            configAddDTOList.add(companyConfigAddDTO);
                        }
                    }
                    companyConfigAddBatchDTO.setUserConfigList(configAddDTOList);
                    BeanUtil.copyProperties(formUpdateDTO, companyConfigAddBatchDTO);
                    companyConfigService.saveBatch(companyConfigAddBatchDTO);
                }
                if (!formSwitches.isEmpty()) {
                    FormConfigAddBatchDTO formConfigAddBatchDTO = new FormConfigAddBatchDTO();
                    List<FormConfigAddDTO> configAddDTOList = new ArrayList<>();
                    for (SwitchsPojo switchsPojo : formSwitches) {
                        List<SwitcherPojo> value = switchsPojo.getValue();
                        for (SwitcherPojo switcherPojo : value) {
                            FormConfigAddDTO formConfigAddDTO = new FormConfigAddDTO();
                            formConfigAddDTO.setConfig(switcherPojo.getConfig());
                            formConfigAddDTO.setConfigValue(switcherPojo.getValue());
                            configAddDTOList.add(formConfigAddDTO);
                        }
                    }
                    BeanUtil.copyProperties(formUpdateDTO, formConfigAddBatchDTO);
                    formConfigAddBatchDTO.setFormConfigList(configAddDTOList);
                    formConfigAddBatchDTO.setSaasMark(paasFormEntity.getSaasMark());
                    formConfigAddBatchDTO.setBusinessType(paasFormEntity.getBusinessType());
                    formConfigService.saveBatch(formConfigAddBatchDTO);
                }

                if (!fieldValueSwitches.isEmpty()) {
                    FormConfigAddBatchDTO formConfigAddBatchDTO = new FormConfigAddBatchDTO();
                    List<FormConfigAddDTO> configAddDTOList = new ArrayList<>();
                    for (SwitchsPojo switchsPojo : fieldValueSwitches) {
                        List<SwitcherPojo> value = switchsPojo.getValue();
                        for (SwitcherPojo switcherPojo : value) {
                            FormConfigAddDTO formConfigAddDTO = new FormConfigAddDTO();
                            formConfigAddDTO.setConfig(switcherPojo.getConfig());
                            formConfigAddDTO.setConfigValue(switcherPojo.getValue());
                            configAddDTOList.add(formConfigAddDTO);
                        }
                    }
                    BeanUtil.copyProperties(formUpdateDTO, formConfigAddBatchDTO);
                    formConfigAddBatchDTO.setFormConfigList(configAddDTOList);
                    formConfigAddBatchDTO.setSaasMark(paasFormEntity.getSaasMark());
                    formConfigAddBatchDTO.setBusinessType(paasFormEntity.getBusinessType());
                    formConfigService.saveBatch(formConfigAddBatchDTO);
                }
            }

            OperateModuleTypeEnum operateModuleType;
            JSONObject oldObj;
            JSONObject newObj;
            String formName;
            if (Objects.equals(formUpdateDTO.getBusinessType(), XbbRefTypeEnum.WORK_ORDER.getCode())) {
                WorkOrderFormEntity entity = workOrderFormModel.getByKey(formUpdateDTO.getFormId(), formUpdateDTO.getCorpid());
                if (Objects.isNull(entity)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
                }
                paasFormEntity.setMenuId(entity.getMenuId());
                operateModuleType = OperateModuleTypeEnum.PAAS_FORM_WORK_ORDER;
                oldObj = JSONObject.parseObject(JSONObject.toJSONString(entity));
                BeanUtil.copyProperties(paasFormEntity, entity);
                workOrderFormModel.update(entity);
                newObj = JSONObject.parseObject(JSONObject.toJSONString(entity));
                formName = entity.getName();
            } else {
                PaasFormEntity entity = paasFormModel.getByKey(formUpdateDTO.getFormId(), formUpdateDTO.getCorpid());
                if (entity == null) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
                }
                paasFormEntity.setMenuId(entity.getMenuId());
                paasFormEntity.setSort(entity.getSort());
                paasFormModel.update(paasFormEntity);
                operateModuleType = OperateModuleTypeEnum.PAAS_FORM;
                oldObj = JSONObject.parseObject(JSONObject.toJSONString(entity));
                newObj = JSONObject.parseObject(JSONObject.toJSONString(paasFormEntity));
                formName = entity.getName();
            }
            // 存放到关联列表里
            paasFormEntity.setName(formName);
            String memo;
            List<DetailLogPojo> detailArr = logHelp.getDetailArr4Normal(corpid, operateModuleType, oldObj, newObj);
            if (detailArr != null) {
                memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_UPDATE_FORM), userName, formName);
                //详情页有更改内容，才记录日志
                mongoLogHelp.buildLog4DetailArr(detailArr, corpid, userId, userName, operateModuleType, OperateTypeEnum.EDIT, paasFormEntity.getId().toString(), formName, memo, formUpdateDTO.getHttpHeader());
            }

            PaasFormExplainEntity paasFormExplainEntity = new PaasFormExplainEntity();
            List<FieldAttrEntity> explains = new ArrayList<>();
            List<FieldAttrEntity> explainList = formUpdateDTO.getExplainList();
            List<Map<String, List<ItemPoJo>>> fieldDependenceList = new ArrayList<>();
            List<Integer> fieldDependenceTypeList = FieldTypeEnum.getFieldDependenceType();
            Map<String, List<RelyPoJo>> productRelyMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            FieldAttrEntity lableEntity = new FieldAttrEntity();
            //评分字段的下标。-1标识是没有评分字段的
            int scoreIndex = -1;
            FieldAttrEntity scoreFieldAttrEntity = new FieldAttrEntity();
            for (int i = 0; i < explainList.size(); i++) {
                FieldAttrEntity fieldAttrEntity = explainList.get(i);
                if (fieldAttrEntity.getFieldType().equals(FieldTypeEnum.SUB_FORM.getType())) {
                    List<FieldAttrEntity> subExplains = new ArrayList<>();
                    Long freezeCount = fieldAttrEntity.getFreezeCount();
                    List<? extends FieldAttrEntity> subExplainList = fieldAttrEntity.getSubForm().getItems();
                    for (int j = 0; j < subExplainList.size(); j++) {
                        FieldAttrEntity subFieldAttr = subExplainList.get(j);
                        subFieldAttr.setSort(j);
                        subExplains.add(subFieldAttr);
                        subFieldAttr.setFixed(Objects.nonNull(freezeCount) && freezeCount-- > 0 ? true : false);
                    }
                    fieldAttrEntity.setSort(i);
                    fieldAttrEntity.getSubForm().setItems(subExplains);
                } else if(fieldAttrEntity.getFieldType().equals(FieldTypeEnum.SELECT_PRODUCT.getType())){
                    List<FieldAttrEntity> subExplains = new ArrayList<>();
                    Long freezeCount = fieldAttrEntity.getFreezeCount();
                    List<? extends FieldAttrEntity> subExplainList = fieldAttrEntity.getSubForm().getItems();
                    FieldAttrEntity productNameAttr = new FieldAttrEntity();
                    for (int j = 0; j < subExplainList.size(); j++) {
                        FieldAttrEntity subFieldAttr = subExplainList.get(j);
                        if (Objects.equals(subFieldAttr.getAttr(), SelectProductEnum.PRODUCT.getAttr())){
                            productNameAttr = subFieldAttr;
                        }
                        subFieldAttr.setSort(j);
                        subExplains.add(subFieldAttr);
                        subFieldAttr.setFixed(Objects.nonNull(freezeCount) && freezeCount-- > 0 ? true : false);
                    }
                    List<LinkedAttrPoJo> linkedAttrPoJos = productNameAttr.getLinkInfo().getLinkedShowAttr();
                    if(productNameAttr.getFixed()){
                        for (int j = 0; j < linkedAttrPoJos.size(); j++) {
                            LinkedAttrPoJo linkedAttrPoJo = linkedAttrPoJos.get(j);
                            linkedAttrPoJo.setFixed(true);
                        }
                    } else{
                        for (int j = 0; j < linkedAttrPoJos.size(); j++) {
                            LinkedAttrPoJo linkedAttrPoJo = linkedAttrPoJos.get(j);
                            linkedAttrPoJo.setFixed(false);
                        }
                    }
                    fieldAttrEntity.getSubForm().setItems(subExplains);
                } else {
                    fieldAttrEntity.setSort(i);
                }
                // 标签字段只存储id
                if (Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.LABEL.getType())){
                    lableEntity = fieldAttrEntity;
                    // deal2Label(formUpdateDTO, corpid, fieldAttrEntity);
                }
                if (Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.SELECT_PRODUCT.getType()) && Objects.nonNull(fieldAttrEntity.getRelyList())) {
                    productRelyMap.put(fieldAttrEntity.getAttr(), fieldAttrEntity.getRelyList());
                    fieldAttrEntity.setRelyList(null);
                }
                //评分字段的visable 是根据是否有启用的评分规则来的（这边把认为修改的口子堵住）
                if(Objects.equals(fieldAttrEntity.getSaasAttr(),"score")){
                    //保存评分字段的index，用于后面调整字段位置
                    scoreIndex = i;
                    //可见性和是否开启同时设置
                    int isOpen = scoreRuleService.haveEnabledScoreRule(corpid, formUpdateDTO.getFormId()) ? 1 : 0;
                    fieldAttrEntity.setIsOpen(isOpen);
                    fieldAttrEntity.setVisible(isOpen);
                    BeanUtil.copyProperties(fieldAttrEntity,scoreFieldAttrEntity);
                }
                //如果是产品表单，新增获取最新多单位逻辑
                if (Objects.equals(formUpdateDTO.getBusinessType(),XbbRefTypeEnum.PRODUCT.getCode())){
                    if (Objects.equals(fieldAttrEntity.getAttr(), ProductEnum.UNIT.getAttr())) {
                        ProductFieldPojo productFieldPojo = saasFormHelp.getProductFieldPojo(RedisPrefixConstant.PRODUCT_UNIT, ProductEnum.UNIT.getAttr(), corpid);
                        fieldAttrEntity.setMultiItems(productFieldPojo.getMultiItems());
                    }
                }
                //字段依赖存对象
                if (fieldDependenceTypeList.contains(fieldAttrEntity.getFieldType())) {
                    List<ItemPoJo> items = fieldAttrEntity.getItems();
                    if (Objects.nonNull(items)) {
                        for (ItemPoJo item : items) {
                            if (Objects.nonNull(item.getSubAttrList()) && !item.getSubAttrList().isEmpty()) {
                                fieldDependenceList.add(item.getSubAttrList());
                            }
                        }
                    }
                }
                explains.add(fieldAttrEntity);
            }
            Map<String, FieldAttrEntity> updateExplainMap = ExplainUtil.getSubFormExplainMapByList(explains);
            handleFieldDependence(fieldDependenceList, updateExplainMap);
            //scoreIndex 大于0表示评分字段是存在的，将它的顺序放到第一位
            if(scoreIndex >= 0){
                explains.remove(scoreIndex);
                explains.add(0,scoreFieldAttrEntity);
            }
            deal2Label(formUpdateDTO, corpid, lableEntity);
            // 字段处理封装
            FieldOptimizationHandle.fieldHandle(explains);
            saveLinkProductRely(formUpdateDTO, corpid, productRelyMap);
            updateDictionaryExpalin(explains,paasFormEntity.getSaasMark(),XbbRefTypeEnum.transferBusinessType4Distributor(paasFormEntity.getBusinessType(), formEntityUpdateDTO.getDistributorMark()),corpid,paasFormEntity.getId());
            // 同步更新表单模板中客户名称和客户电话的查重配置
            if ((Objects.equals(formEntityUpdateDTO.getBusinessType(), XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode()) && !Objects.equals(formEntityUpdateDTO.getDistributorMark(), DistributorMarkEnum.DISTRIBUTOR.getCode()))
                    || Objects.equals(formEntityUpdateDTO.getBusinessType(), XbbRefTypeEnum.CLUE.getCode())) {
                syncCustomerRepeatType(formUpdateDTO, explainList, formName, formEntityUpdateDTO.getBusinessType());
            }
            if (XbbRefTypeEnum.checkRecheckRuleBusinessType(formEntityUpdateDTO.getBusinessType())) {
                // 查重2.0 同步解释中开启了新进不允许重复的字段到 新的 重复规则表里面
                recheckingRuleService.syncExplainsToRecheckRule(corpid,explainList,formEntityUpdateDTO.getId(),formEntityUpdateDTO.getBusinessType());
            }

            paasFormExplainEntity.setExplains(JSONArray.toJSONString(explains));
            paasFormExplainEntity.setFormId(formUpdateDTO.getFormId());
            paasFormExplainEntity.setCorpid(formUpdateDTO.getCorpid());
            paasFormExplainEntity.setAppId(formUpdateDTO.getAppId());
            paasFormExplainEntity.setId(formUpdateDTO.getFormExplainId());
            List<FieldAttrEntity> addAttr = new ArrayList<>();
            List<FieldAttrEntity> updateAttr = new ArrayList<>();
            if (Objects.equals(formUpdateDTO.getBusinessType(), XbbRefTypeEnum.WORK_ORDER.getCode())) {
                //工单
                WorkOrderExplainEntity explainEntity = workOrderExplainModel.getByKey(formUpdateDTO.getFormExplainId(), formUpdateDTO.getCorpid());
                if (Objects.isNull(explainEntity)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
                }
                Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(explainEntity.getExplains());
                getAddAttrList(explains, addAttr, explainMap, updateAttr);
                // 设置关联列表
                paasFormEntity.setBusinessType(XbbRefTypeEnum.WORK_ORDER.getCode());
                paasFormEntity.setSaasMark(SaasMarkEnum.SAAS.getCode());
                saveLinkListInfo(JSONArray.parseArray(explainEntity.getExplains(), FieldAttrEntity.class), explains, paasFormEntity, formUpdateDTO);
                operateModuleType = OperateModuleTypeEnum.PAAS_FORM_EXPLAIN_WORK_ORDER;
                oldObj = JSONObject.parseObject(JSONObject.toJSONString(explainEntity));
                BeanUtil.copyProperties(paasFormExplainEntity, explainEntity);
                workOrderExplainModel.update(explainEntity);
                newObj = JSONObject.parseObject(JSONObject.toJSONString(explainEntity));
            } else {
                //其他业务
                PaasFormExplainEntity explainEntity = paasFormExplainModel.getByKey(formUpdateDTO.getFormExplainId().intValue(), formUpdateDTO.getCorpid());
                if (explainEntity == null) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
                }
                Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(explainEntity.getExplains());
                getAddAttrList(explains, addAttr, explainMap, updateAttr);
                // 设置关联列表
                saveLinkListInfo(JSONArray.parseArray(explainEntity.getExplains(), FieldAttrEntity.class), explains, paasFormEntity, formUpdateDTO);
                paasFormExplainEntity.setBusinessType(explainEntity.getBusinessType());
                //根据应收规则，处理表单模板（防止模板字段未和最新的应收规则匹配，保存前做一次处理）
                fundSetService.handleSpecialExplain(corpid, paasFormExplainEntity);
                // 表单解释保存之前，校验多版本启用时设置的默认版本是否合法
                stageProcessService.validateMultiVersionDefaultStageProcess(explains, corpid, formUpdateDTO.getFormId());
                paasFormExplainModel.update(paasFormExplainEntity);
                //回款单模板回款金额精度变化时。同步更新预收款余额精度; 付款单模板付款金额精度发生变化时，同步更新预付款余额精度。
                paasFormExplainEntity.setDistributorMark(explainEntity.getDistributorMark());
                handleMoneyAccuracy(formUpdateDTO.getBusinessType(),paasFormExplainEntity,corpid);
                operateModuleType = OperateModuleTypeEnum.PAAS_FORM_EXPLAIN;
                oldObj = JSONObject.parseObject(JSONObject.toJSONString(explainEntity));
                newObj = JSONObject.parseObject(JSONObject.toJSONString(paasFormExplainEntity));
                //产品表单编辑，去除单价、成本、库存、单位缓存
                if (Objects.equals(XbbRefTypeEnum.PRODUCT.getCode(),formUpdateDTO.getBusinessType())){
                    paasRedisHelper.removeValue(RedisPrefixConstant.PRODUCT_COST,corpid);
                    paasRedisHelper.removeValue(RedisPrefixConstant.PRODUCT_STOCK,corpid);
                    paasRedisHelper.removeValue(RedisPrefixConstant.PRODUCT_PRICE,corpid);
                    paasRedisHelper.removeValue(RedisPrefixConstant.PRODUCT_UNIT,corpid);
                }
            }
            //将表单解释中的阶段 默认值和关联选址值 置入阶段表
            StageHandle stageHandle = stageHandleFactory.getStageHandle(formUpdateDTO.getSaasMark(), formUpdateDTO.getBusinessType());
            if (Objects.nonNull(stageHandle)) {
                stageHandle.updateStageDefaultAndOption(explains, formUpdateDTO.getFormId(), corpid);
            }
            // 流程权限的新增
            if (!addAttr.isEmpty() || CollectionsUtil.isNotEmpty(updateAttr)) {
                Runnable runnable = () -> {
                    Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    params.put("corpid", corpid);
                    params.put("formId", formUpdateDTO.getFormId());
                    params.put("appId", formUpdateDTO.getAppId());
                    params.put("del", 0);
                    params.put("typeIn", Arrays.asList(NodeTypeEnum.PROCESS_NODE.getNodeType(), NodeTypeEnum.START_PROCESS_NODE.getNodeType(), NodeTypeEnum.CC_PROCESS_NODE.getNodeType()));
                    Integer totalCount = paasProcessTemplateNodeModel.getEntitysCount(params);
                    int pageSize = 100;
                    int totalPage = (totalCount % pageSize == 0) ? (totalCount / pageSize) : (totalCount / pageSize) + 1;
                    for (int page = 0; page < totalPage; page++) {
                        int start = page * pageSize;
                        params.put("start", start);
                        params.put("pageNum", pageSize);
                        List<PaasProcessTemplateNodeEntityExt> templateNodeList = paasProcessTemplateNodeModel.list(params);
                        List<PaasProcessTemplateNodeEntityExt> updateNodeList = new ArrayList<>();
                        for (PaasProcessTemplateNodeEntityExt nodeEntity : templateNodeList) {
                            PaasProcessTemplateNodeEntityExt updateNodeEntity = new PaasProcessTemplateNodeEntityExt();
                            updateNodeEntity.setId(nodeEntity.getId());
                            List<FieldPermissionEntityExt> permissionList = nodeEntity.getFieldPermissionList();
                            for (FieldAttrEntity fieldAttrEntity : addAttr) {
                                String attr = fieldAttrEntity.getAttr();
                                if (attr.contains(StringConstant.POINT)) {
                                    String[] args = attr.split("\\" + StringConstant.POINT);
                                    FieldPermissionEntityExt fieldPermissionEntityExt = new FieldPermissionEntityExt(args[0], args[1], fieldAttrEntity.getFieldType(), 0, 1, 0);
                                    permissionList.add(fieldPermissionEntityExt);
                                } else {
                                    FieldPermissionEntityExt fieldPermissionEntityExt = new FieldPermissionEntityExt(attr, fieldAttrEntity.getFieldType(), 0, 1, 0);
                                    permissionList.add(fieldPermissionEntityExt);
                                }
                            }
                            if (CollectionsUtil.isNotEmpty(updateAttr)) {
                                for (FieldPermissionEntityExt fieldPermissionEntityExt : permissionList) {
                                    if (Objects.equals(fieldPermissionEntityExt.getAttr(), FieldTypeEnum.SERIALNO.getAlias())){
                                        fieldPermissionEntityExt.setEditable(BasicConstant.ZERO);
                                    }
                                }
                            }
                            updateNodeEntity.setFieldPermission(JSON.toJSONString(permissionList));
                            updateNodeList.add(updateNodeEntity);
                        }
                        templateNodeList.clear();
                        paasProcessTemplateNodeModel.updateBatch(updateNodeList, corpid);
                    }
                };
                threadPoolBeanConfig.updateSmsStatusThreadPool().execute(runnable);
            }
            // TODO 删除字段，同步删除字段相应的数据
            // 记录日志
            detailArr = logHelp.getDetailArr4Normal(corpid, operateModuleType, oldObj, newObj);
            if (detailArr != null) {
                memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_UPDATE_FORM_EXPLAIN), userName, formName);
                String opObjectName = formName + I18nMessageUtil.getMessage(I18nStringConstant.FIELD_EXPLAIN);
                mongoLogHelp.buildLog4DetailArr(detailArr, corpid, userId, userName, operateModuleType, OperateTypeEnum.EDIT, paasFormExplainEntity.getId().toString(), opObjectName, memo, formUpdateDTO.getHttpHeader());
            }

            // 字段回收站保存处理
            Map<String, Object> param = new HashMap<>();
            param.put("corpid", corpid);
            param.put("menuId", formUpdateDTO.getMenuId());
            param.put("formId", formUpdateDTO.getFormId());
            param.put("appId", formUpdateDTO.getAppId());
            param.put("recover", 0);
            param.put("del", DelEnum.NORMAL.getDel());
            List<AttrTrashEntity> attrTrashEntityList = attrTrashModel.findEntitys(param);
            Map<String, AttrTrashEntity> trashMap = new HashMap<>();
            attrTrashEntityList.forEach(v -> trashMap.put(v.getAttr(), v));

            Set<String> trashList = formUpdateDTO.getTrashList();
            if (Objects.nonNull(trashList)) {
                List<AttrTrashEntity> updateTrashList = new ArrayList<>();
                List<AttrTrashEntity> addTrashList = new ArrayList<>();
                for (String attr : trashList) {
                    if (trashMap.containsKey(attr)) {
                        updateTrashList.add(trashMap.get(attr));
                        trashMap.remove(attr);
                    } else {
                        addTrashList.add(new AttrTrashEntity(corpid, formUpdateDTO.getAppId(), formUpdateDTO.getMenuId(), formUpdateDTO.getFormId(), paasFormEntity.getSaasMark(), paasFormEntity.getBusinessType(), attr, formUpdateDTO.getUserId()));
                    }
                }
                if (addTrashList.size() > 0) {
                    attrTrashModel.insertBatch(addTrashList);
                }
                if (updateTrashList.size() > 0) {
                    attrTrashModel.updateBatch(updateTrashList, corpid);
                }
                List<Long> delIds = new ArrayList<>();
                trashMap.forEach((k, v) -> delIds.add(v.getId()));
                if (delIds.size() > 0) {
                    attrTrashModel.deleteBatch(delIds, corpid);
                }
            }


            formUpdateVO.setAppId(formUpdateDTO.getAppId());
            formUpdateVO.setFormId(formUpdateDTO.getFormId());
            if (Objects.nonNull(formUpdateDTO.getFormAttr().getAssignmentRules())) {
                formConfigModel.save(RedisPrefixConstant.ASSIGNMENT_RULES, corpid, formUpdateDTO.getFormId(), formUpdateDTO.getSaasMark(), formUpdateDTO.getBusinessType(), formUpdateDTO.getFormAttr().getAssignmentRules().toString());
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasForm数据库保存出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formUpdateVO;
    }

    /**
     * 处理字段依赖，根据value值刷新（利用引用）
     * @param fieldDependenceList
     * @param updateExplainMap
     */
    private void handleFieldDependence(List<Map<String, List<ItemPoJo>>> fieldDependenceList, Map<String, FieldAttrEntity> updateExplainMap) {
        if (CollectionsUtil.isEmpty(fieldDependenceList)) {
            return;
        }
        for (Map<String, List<ItemPoJo>> fieldDependenceMap : fieldDependenceList) {
            if (fieldDependenceMap.isEmpty()) {
                continue;
            }
            for (Map.Entry<String, List<ItemPoJo>> stringListEntry : fieldDependenceMap.entrySet()) {
                String attr = stringListEntry.getKey();
                List<ItemPoJo> subAttrFields = stringListEntry.getValue();
                FieldAttrEntity fieldAttrEntity = updateExplainMap.get(attr);
                Map<Object, ItemPoJo> itemPoJoMap;
                if (Objects.nonNull(fieldAttrEntity) && Objects.nonNull(fieldAttrEntity.getItems())) {
                    itemPoJoMap = fieldAttrEntity.getItems().stream().collect(Collectors.toMap(ItemPoJo::getValue, item -> item, (a, b) -> b));
                    for (Iterator<ItemPoJo> iterator = subAttrFields.iterator(); iterator.hasNext(); ) {
                        ItemPoJo subAttrField = iterator.next();
                        ItemPoJo itemPoJo = itemPoJoMap.get(subAttrField.getValue());
                        if (Objects.isNull(itemPoJo)) {
                            iterator.remove();
                            continue;
                        }
                        subAttrField.setChecked(itemPoJo.getChecked());
                        subAttrField.setColor(itemPoJo.getColor());
                        subAttrField.setFieldMap(itemPoJo.getFieldMap());
                        subAttrField.setIsOther(itemPoJo.getIsOther());
                        subAttrField.setText(itemPoJo.getText());
                    }
                }
            }
        }
    }

    public void deal2Label(FormUpdateDTO formUpdateDTO, String corpid, FieldAttrEntity fieldAttrEntity) throws XbbException {
        if (Objects.nonNull(fieldAttrEntity.getDefaultAttr()) && Objects.nonNull(fieldAttrEntity.getDefaultAttr().getDefaultValue())){
            // 保存的时候判断标签默认值中是否包含移入回收站的标签
            Object defaultValue1 = fieldAttrEntity.getDefaultAttr().getDefaultValue();
            if (defaultValue1 instanceof ArrayList){
                List<Object> defaultValue = (ArrayList)defaultValue1;
                List<Long> labelIds = new ArrayList<>();
                for (Object o : defaultValue) {
                    LinkedHashMap<String ,Object> map =(LinkedHashMap)o;
                    labelIds.add(Long.parseLong(map.get("id").toString()));
                }
                if (labelIds.size()>0) {
                    proFormHelp.checkLabelExistis(labelIds, corpid, BasicConstant.TWO);
                }

                fieldAttrEntity.getDefaultAttr().setDefaultValue(labelIds);
            }
        } else {
            labelHelp.initLabel(corpid,formUpdateDTO.getAppId(), formUpdateDTO.getFormId(), formUpdateDTO.getBusinessType(), formUpdateDTO.getUserId(), false);
        }
    }

    /**
     * 处理预收款和预付款的精度问题，预收款余额精度需要跟回款单付款金额一直。预付款余额进度需要跟付款单金额精度一直
     *
     * @param businessType 业务类型
     * @param paasFormExplainEntity
     * @param corpid 公司id
     */
    private void handleMoneyAccuracy(Integer businessType, PaasFormExplainEntity paasFormExplainEntity, String corpid) throws XbbException {
        if(Objects.equals(businessType,XbbRefTypeEnum.PAYMENT_SHEET.getCode())){
            PaasFormExplainEntity balanceExplainEntity = paasFormExplainModel.getByBusinessType4Distributor(XbbRefTypeEnum.PREPAYMENT_BALANCE.getCode(), corpid, paasFormExplainEntity.getDistributorMark());
            if(balanceExplainEntity != null){
                List<FieldAttrEntity> fieldList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
                Integer accuracy = null;
                for (FieldAttrEntity  attrEntity : fieldList) {
                    if(Objects.equals(attrEntity.getAttr(), PaymentSheetEnum.AMOUNT.getAttr())){
                        accuracy = attrEntity.getAccuracy();
                        break;
                    }
                }
                if(accuracy != null){
                    List<FieldAttrEntity> balanceExplains = JSONArray.parseArray(balanceExplainEntity.getExplains(), FieldAttrEntity.class);
                    Iterator<FieldAttrEntity> iterator = balanceExplains.iterator();
                    while (iterator.hasNext()){
                        FieldAttrEntity fieldAttr = iterator.next();
                        if(Objects.equals(fieldAttr.getAttr(), PaymentBalanceEnum.ADVANCE_PAYMENT_BALANCE.getAttr())){
                            fieldAttr.setAccuracy(accuracy);
                            break;
                        }
                    }
                    balanceExplainEntity.setExplains(JSON.toJSONString(balanceExplains));
                    paasFormExplainModel.update(balanceExplainEntity);
                }
            }
        } else if (Objects.equals(businessType,XbbRefTypeEnum.PAY_SHEET.getCode())){
            PaasFormExplainEntity balanceExplainEntity = paasFormExplainModel.getByBusinessType(XbbRefTypeEnum.PREPAY_BALANCE.getCode(), corpid);
            if(balanceExplainEntity != null){
                List<FieldAttrEntity> fieldList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
                Integer accuracy = null;
                for (FieldAttrEntity  attrEntity : fieldList) {
                    if(Objects.equals(attrEntity.getAttr(), PaySheetEnum.AMOUNT.getAttr())){
                        accuracy = attrEntity.getAccuracy();
                        break;
                    }
                }
                if(accuracy != null){
                    List<FieldAttrEntity> balanceExplains = JSONArray.parseArray(balanceExplainEntity.getExplains(), FieldAttrEntity.class);
                    Iterator<FieldAttrEntity> iterator = balanceExplains.iterator();
                    while (iterator.hasNext()){
                        FieldAttrEntity fieldAttr = iterator.next();
                        if(Objects.equals(fieldAttr.getAttr(), PayBalanceEnum.ADVANCE_PAY_BALANCE.getAttr())){
                            fieldAttr.setAccuracy(accuracy);
                            break;
                        }
                    }
                    balanceExplainEntity.setExplains(JSON.toJSONString(balanceExplains));
                    paasFormExplainModel.update(balanceExplainEntity);
                }
            }
        }
    }

    private void saveLinkProductRely(FormUpdateDTO formUpdateDTO, String corpid, Map<String, List<RelyPoJo>> productRelyMap) throws XbbException {
        if (!productRelyMap.isEmpty()) {
            List<LinkProductRelyEntity> productRelyEntityList = linkProductRelyModel.getByFormId(corpid, formUpdateDTO.getFormId(), DelEnum.NORMAL.getDel());
            Map<String, List<LinkProductRelyEntity>> existProductRelyMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            List<LinkProductRelyEntity> relyEntityList;
            for (LinkProductRelyEntity linkProductRelyEntity : productRelyEntityList) {
                relyEntityList = existProductRelyMap.getOrDefault(linkProductRelyEntity.getField(), new ArrayList<>());
                relyEntityList.add(linkProductRelyEntity);
                existProductRelyMap.put(linkProductRelyEntity.getField(), relyEntityList);
            }
            List<LinkProductRelyEntity> newRelyEntityList = new ArrayList<>();
            List<LinkProductRelyEntity> updateRelyEntityList = new ArrayList<>();
            for (Map.Entry<String, List<RelyPoJo>> entry : productRelyMap.entrySet()) {
                List<LinkProductRelyEntity> existRelyList = existProductRelyMap.getOrDefault(entry.getKey(), new ArrayList<>());
                Map<Long, LinkProductRelyEntity> oldLinkFormRelyMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                existRelyList.forEach(linkProductRelyEntity-> oldLinkFormRelyMap.put(linkProductRelyEntity.getSourceFormId(), linkProductRelyEntity));
                List<RelyPoJo> newRelyList = entry.getValue();
                for (RelyPoJo relyPoJo : newRelyList) {
                    if (oldLinkFormRelyMap.containsKey(relyPoJo.getSourceFormId())) {
                        LinkProductRelyEntity linkProductRelyEntity = oldLinkFormRelyMap.get(relyPoJo.getSourceFormId());
                        linkProductRelyEntity.setSubRelyFieldList(JSONArray.parseArray(JSON.toJSONString(relyPoJo.getSubRelyFieldList())));
                        updateRelyEntityList.add(linkProductRelyEntity);
                    } else {
                        LinkProductRelyEntity linkProductRelyEntity = new LinkProductRelyEntity();
                        BeanUtil.copyProperties(relyPoJo, linkProductRelyEntity);
                        linkProductRelyEntity.setField(entry.getKey());
                        linkProductRelyEntity.setFormId(formUpdateDTO.getFormId());
                        linkProductRelyEntity.setSubRelyFieldList(JSONArray.parseArray(JSON.toJSONString(relyPoJo.getSubRelyFieldList())));
                        linkProductRelyEntity.setCorpid(corpid);
                        linkProductRelyEntity.setCreatorId(formUpdateDTO.getUserId());
                        linkProductRelyEntity.setBusinessType(formUpdateDTO.getBusinessType());
                        linkProductRelyEntity.setSourceBusinessType(relyPoJo.getSourceBusinessType());
                        newRelyEntityList.add(linkProductRelyEntity);
                    }
                }
                Map<Long, RelyPoJo> newLinkFormRelyMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                newRelyList.forEach(relyPoJo -> newLinkFormRelyMap.put(relyPoJo.getSourceFormId(), relyPoJo));
                for (LinkProductRelyEntity linkProductRelyEntity : existRelyList) {
                    if (!newLinkFormRelyMap.containsKey(linkProductRelyEntity.getSourceFormId())) {
                        linkProductRelyEntity.setDel(DelEnum.DELETE.getDel());
                        updateRelyEntityList.add(linkProductRelyEntity);
                    }
                }
            }
            if (CollectionsUtil.isNotEmpty(newRelyEntityList)) {
                if (newRelyEntityList.size() == 1) {
                    linkProductRelyModel.insert(newRelyEntityList.get(0));
                } else {
                    linkProductRelyModel.insertBatch(newRelyEntityList);
                }
            }
            if (CollectionsUtil.isNotEmpty(updateRelyEntityList)) {
                if (updateRelyEntityList.size() == 1) {
                    linkProductRelyModel.update(updateRelyEntityList.get(0));
                } else {
                    linkProductRelyModel.updateBatch(updateRelyEntityList);
                }
            }
        }
    }

    private void getAddAttrList(List<FieldAttrEntity> explains, List<FieldAttrEntity> addAttr, Map<String, FieldAttrEntity> explainMap, List<FieldAttrEntity> updateAttr) {
        for (FieldAttrEntity explain : explains) {
            String attr = explain.getAttr();
            if (!explainMap.containsKey(attr)) {
                addAttr.add(explain);
            }
            if (Objects.equals(explain.getFieldType(), FieldTypeEnum.SUB_FORM.getType())) {
                List<? extends FieldAttrEntity> subExplainList = explain.getSubForm().getItems();
                for (FieldAttrEntity fieldAttrEntity : subExplainList) {
                    String key = attr + StringConstant.POINT + fieldAttrEntity.getAttr();
                    if (!explainMap.containsKey(key)) {
                        fieldAttrEntity.setAttr(key);
                        addAttr.add(fieldAttrEntity);
                    }
                }
            }
            if (Objects.equals(attr, FieldTypeEnum.SERIALNO.getAlias()) && Objects.equals(explain.getStrictController(), BasicConstant.ONE)){
                updateAttr.add(explain);
            }
        }
    }

    /**
     * 用于更新数据字典的名称以及排序
     * PLAN A:直接拿前端传入值，更新覆盖，弊端，数据不及时，缺少数据
     * PKAN B:取数据库数据，弊端，排序麻烦
     */
    private void updateDictionaryExpalin(List<FieldAttrEntity> explains, Integer saasMark, Integer businessType, String corpid, Long formId) throws XbbException {
        if (!Objects.equals(saasMark,SaasMarkEnum.SAAS.getCode())){
            return;
        }
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        for (FieldAttrEntity entity : explains) {
            DictionaryEnum dictionaryEnum = null;
            String attr = entity.getAttr();
            switch (xbbRefTypeEnum) {
                case CUSTOMER_MANAGEMENT:
                    // 客户状态
                    if (Objects.equals(attr, CustomerManagementEnum.TYPE.getAttr())) {
                        dictionaryEnum = DictionaryEnum.CUSTOMER_STATUS;
                    }
                    if (Objects.equals(attr, CustomerManagementEnum.WASTAGE.getAttr())) {
                        dictionaryEnum = DictionaryEnum.CUSTOMER_STAGE_WASTAGE;
                    }
                    break;
                case CLUE:
                    // 线索阶段
                    if (Objects.equals(attr, ClueEnum.INVALID_REASON.getAttr())) {
                        dictionaryEnum = DictionaryEnum.CLUE_STAGE_INVALID;
                    }
                    break;
                case CONTRACT:
                    // 合同状态
                    if (Objects.equals(attr, ContractEnum.STATUS.getAttr())) {
                        dictionaryEnum = DictionaryEnum.CONTRACT_STATUS;
                    }
                    // 物流公司
                    if (Objects.equals(attr, ContractEnum.EXPRESS_NAME.getAttr())) {
                        dictionaryEnum = DictionaryEnum.EXPRESS_NAME;
                    }
                    break;
                case SALES_OPPORTUNITY:
                    // 销售阶段下拉项设置不允许编辑删除，流失原因不允许移动
                    if (Objects.equals(attr, SalesOpportunityEnum.WASTAGE.getAttr())) {
                        dictionaryEnum = DictionaryEnum.SALE_STAGE_WASTAGE;
                    }
                    break;
                case OUTSTOCK:
                case CONTRACT_OUTSTOCK:
                case RETURNED_PURCHASE_OUTSTOCK:
                case OTHER_OUTSTOCK:
                case PRODUCTION_MATERIEL_OUTSTOCK:
                case WORK_ORDER_OUTSTOCK:
                    // 物流公司
                    if (Objects.equals(attr, OutstockEnum.EXPRESS_NAME.getAttr())) {
                        dictionaryEnum = DictionaryEnum.EXPRESS_NAME;
                    }
                    break;
                /*case CUSTOMER_COMMUNICATE:
                    // 客户状态
                    if (Objects.equals(attr, CustomerCommunicateEnum.CUSTOMER_STATUS.getAttr())) {
                        dictionaryEnum = DictionaryEnum.CUSTOMER_STATUS;
                    }
                    break;*/
                case COMMUNICATE_PLAN:
                    // 延期原因
                    if (Objects.equals(attr, CommunicatePlanEnum.DELAY_CAUSE.getAttr())) {
                        dictionaryEnum = DictionaryEnum.DELAY_CAUSE;
                    }
                    break;
                default:
                    return;
            }
            if (Objects.nonNull(dictionaryEnum)){
                DataDictionaryEntity dataDictionaryEntity;
                if (Objects.equals(dictionaryEnum.getDictionaryTermEnum().getCode(),DictionaryTermEnum.DATA_DICTIONARY_TERM.getCode())){
                    dataDictionaryEntity = dataDictionaryModel.getByType(dictionaryEnum.getType(), corpid);
                }else {
                    dataDictionaryEntity = formDataDictionaryModel.getByType(dictionaryEnum.getType(), corpid, formId);
                }
                if (Objects.nonNull(dataDictionaryEntity)) {
                    List<DictionaryPojo> dictionaryPojoList = JSONArray.parseArray(dataDictionaryEntity.getData(),DictionaryPojo.class);
                    List<ItemPoJo> itemPoJoList = Objects.nonNull(entity.getItems()) ? entity.getItems() : new ArrayList<>();
                    Map<String,String> nameSortMap = new LinkedHashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    Map<String,DictionaryPojo> dictionaryPojoMap = new LinkedHashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    for (ItemPoJo itemPoJo : itemPoJoList){
                        nameSortMap.put(itemPoJo.getValue().toString(),itemPoJo.getText());
                    }
                    for (DictionaryPojo dictionaryPojo : dictionaryPojoList){
                        dictionaryPojoMap.put(dictionaryPojo.getValue(),dictionaryPojo);
                    }
                    List<DictionaryPojo> updateList = new ArrayList<>();
                    int index = 0;
                    boolean sort = false;
                    for (Map.Entry<String,String> entry : nameSortMap.entrySet()){
                        DictionaryPojo dictionaryPojo = dictionaryPojoMap.get(entry.getKey());
                        if (Objects.nonNull(dictionaryPojo)) {
                            if (!Objects.equals(dictionaryPojo.getText(),entry.getValue()) || !Objects.equals(dictionaryPojoList.indexOf(dictionaryPojo),index)){
                                sort = true;
                            }
                            dictionaryPojo.setText(entry.getValue());
                            updateList.add(dictionaryPojo);
                            dictionaryPojoMap.remove(entry.getKey());
                            index++;
                        }
                    }
                    if (!sort){
                        continue;
                    }
                    for (Map.Entry<String,DictionaryPojo> entry : dictionaryPojoMap.entrySet()){
                        updateList.add(entry.getValue());
                    }
                    if (Objects.equals(dictionaryEnum.getDictionaryTermEnum().getCode(),DictionaryTermEnum.DATA_DICTIONARY_TERM.getCode())){
                        dataDictionaryModel.removeRedis(corpid,dictionaryEnum.getType());
                        dataDictionaryModel.update(dataDictionaryEntity.getId(),corpid,JSONArray.toJSONString(updateList));
                    }else {
                        formDataDictionaryModel.removeRedis(corpid,formId,dictionaryEnum);
                        formDataDictionaryModel.update(dataDictionaryEntity.getId(),corpid,JSONArray.toJSONString(updateList),formId);
                    }
                }
            }
        }
    }

    /**
     * 获取关联数据的字段，用于存储到关联列表的设置页面
     * @param oldExplainList
     * @param newExplainList
     */
    private void saveLinkListInfo(List<FieldAttrEntity> oldExplainList,
                             List<FieldAttrEntity> newExplainList, PaasFormEntity paasFormEntity, FormUpdateDTO formUpdateDTO) throws XbbException {
        Map<String, FieldAttrEntity> oldExplainMap = linkMap(oldExplainList);
        Map<String, FieldAttrEntity> newExplainMap = linkMap(newExplainList);
        Iterator<String> oldIterator = oldExplainMap.keySet().iterator();
        List<RelatedLinkInfoPojo> deleteLinkInfoList = new ArrayList<>();
        List<RelatedLinkInfoPojo> addLinkInfoList = new ArrayList<>();
        while (oldIterator.hasNext()) {
            String oldKey = oldIterator.next();
            if (newExplainMap.containsKey(oldKey)) {
                FieldAttrEntity oldField = oldExplainMap.get(oldKey);
                FieldAttrEntity newField = newExplainMap.get(oldKey);
                LinkInfoPojo oldLinkInfo = oldField.getLinkInfo();
                RelatedLinkInfoPojo oldRelated = new RelatedLinkInfoPojo();
                BeanUtil.copyProperties(oldLinkInfo, oldRelated);
                oldRelated.setAttr(oldKey);
                LinkInfoPojo newLinkInfo = newField.getLinkInfo();
                RelatedLinkInfoPojo newRelated = new RelatedLinkInfoPojo();
                BeanUtil.copyProperties(newLinkInfo, newRelated);
                newRelated.setAttr(oldKey);
                // 包含工单
                if (Objects.isNull(oldLinkInfo.getLinkFormId())) {
                    addLinkInfoList.add(newRelated);
                }
                if (!Objects.equals(newLinkInfo.getLinkFormId(), oldLinkInfo.getLinkFormId())
                        && !Objects.equals(newLinkInfo.getLinkBusinessType(), oldLinkInfo.getLinkBusinessType())) {
                    // 工单的删除，因为他的表单id可能一致
                    deleteLinkInfoList.add(oldRelated);
                    addLinkInfoList.add(newRelated);
                } else if (!Objects.equals(newLinkInfo.getLinkFormId(), oldLinkInfo.getLinkFormId())
                        && Objects.equals(newLinkInfo.getLinkBusinessType(), oldLinkInfo.getLinkBusinessType())) {
                    // 非工单的删除，因为他的表单id可能一致
                    deleteLinkInfoList.add(oldRelated);
                    addLinkInfoList.add(newRelated);
                } else if (Objects.equals(newLinkInfo.getLinkFormId(), oldLinkInfo.getLinkFormId())
                        && Objects.equals(newLinkInfo.getLinkBusinessType(), oldLinkInfo.getLinkBusinessType())) {
                    // 相同的业务类型，相同的表单id，进行添加操作
                    addLinkInfoList.add(newRelated);
                }
            }else if (!newExplainMap.containsKey(oldKey) || newExplainMap.isEmpty()) {
                // 删除字段的时候，删除其关联列表对应的数据
                FieldAttrEntity oldField = oldExplainMap.get(oldKey);
                RelatedLinkInfoPojo oldRelated = new RelatedLinkInfoPojo();
                LinkInfoPojo oldLinkInfo = oldField.getLinkInfo();
                BeanUtil.copyProperties(oldLinkInfo, oldRelated);
                oldRelated.setAttr(oldKey);
                deleteLinkInfoList.add(oldRelated);
            }
        }
        Iterator<String> newIterator = newExplainMap.keySet().iterator();
        while (newIterator.hasNext()) {
            String key = newIterator.next();
            if (!oldExplainMap.containsKey(key)) {
                FieldAttrEntity newField = newExplainMap.get(key);
                LinkInfoPojo newLinkInfo = newField.getLinkInfo();
                RelatedLinkInfoPojo newRelated = new RelatedLinkInfoPojo();
                BeanUtil.copyProperties(newLinkInfo, newRelated);
                newRelated.setAttr(key);
                // 包含工单
                addLinkInfoList.add(newRelated);
            }
        }
        deleteAssociationList(formUpdateDTO, deleteLinkInfoList, paasFormEntity);
        updateAssociationList(formUpdateDTO, addLinkInfoList, paasFormEntity);
    }

    /**
     * 更新关联列表
     * @param formUpdateDTO
     * @param addLinkInfoList 需要增加的关联列表
     * @param paasFormEntity 本表单
     * @throws XbbException
     */
    private void updateAssociationList(FormUpdateDTO formUpdateDTO, List<RelatedLinkInfoPojo> addLinkInfoList, PaasFormEntity paasFormEntity) throws XbbException {
        if (addLinkInfoList.isEmpty()) {
            return;
        }
        String corpid = formUpdateDTO.getCorpid();
        List<Long> addFormId = new ArrayList<>();
        List<Long> addWorkOrderFormId = new ArrayList<>();
        addLinkInfoList.forEach(item->{
            if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), item.getLinkBusinessType())) {
                addWorkOrderFormId.add(item.getLinkFormId());
            } else {
                addFormId.add(item.getLinkFormId());
            }
        });
        Map<Long, List<RelatedLinkInfoPojo>> addLinkListPojoMap = new HashMap<>(addLinkInfoList.size());
        Map<Long, List<RelatedLinkInfoPojo>> addWorkOrderLinkListMap = new HashMap<>(addLinkInfoList.size());
        addLinkInfoList.forEach(item->{
            List<RelatedLinkInfoPojo> list = new ArrayList<>();
            if (!Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), item.getLinkBusinessType())) {
                if (addLinkListPojoMap.containsKey(item.getLinkFormId())) {
                    list = addLinkListPojoMap.get(item.getLinkFormId());
                    list.add(item);
                    addLinkListPojoMap.put(item.getLinkFormId(), list);
                } else {
                    list.add(item);
                    addLinkListPojoMap.put(item.getLinkFormId(), list);
                }
            } else {
                if (addWorkOrderLinkListMap.containsKey(item.getLinkFormId())) {
                    list = addWorkOrderLinkListMap.get(item.getLinkFormId());
                    list.add(item);
                    addWorkOrderLinkListMap.put(item.getLinkFormId(), list);
                } else {
                    list.add(item);
                    addWorkOrderLinkListMap.put(item.getLinkFormId(), list);
                }
            }
        });
        if (!addWorkOrderFormId.isEmpty()) {
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", paasFormEntity.getCorpid());
            param.put("del", DelEnum.NORMAL.getDel());
            param.put("idIn", addWorkOrderFormId);
            List<WorkOrderFormEntity> workOrderFormList = workOrderFormModel.findEntitys(param);
            if (Objects.isNull(workOrderFormList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
            FormUpdateBatchDTO formUpdateBatchDTO = new FormUpdateBatchDTO();
            BeanUtil.copyProperties(formUpdateDTO, formUpdateBatchDTO);

            List<PaasFormEntityExt> formList = new ArrayList<>();
            try {
                BeanUtil.copyPropertiesList(workOrderFormList, formList, PaasFormEntityExt.class);
            }catch (Exception e) {
                LOG.error("formServeice.updateAssociationList拷贝出错", e);
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
            List<FormEntityUpdateDTO> updateList = getUpdateFormList(formList, paasFormEntity, addWorkOrderLinkListMap);
            if (!updateList.isEmpty()) {
                formUpdateBatchDTO.setFormList(updateList);
                workOrderFormService.updateBatch(formUpdateBatchDTO);
                // 保存日志
                saveLogger(formUpdateDTO.getLoginUser(), corpid, formUpdateDTO.getHttpHeader(), updateList);
            }
        }
        if (!addFormId.isEmpty()) {
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", paasFormEntity.getCorpid());
            param.put("del", DelEnum.NORMAL.getDel());
            param.put("idIn", addFormId);
            List<PaasFormEntityExt> formList = paasFormModel.list(param);
            if (Objects.isNull(formList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
            FormUpdateBatchDTO formUpdateBatchDTO = new FormUpdateBatchDTO();
            BeanUtil.copyProperties(formUpdateDTO, formUpdateBatchDTO);
            List<FormEntityUpdateDTO> updateList = getUpdateFormList(formList, paasFormEntity, addLinkListPojoMap);

            if (!updateList.isEmpty()) {
                formUpdateBatchDTO.setFormList(updateList);
                updateBatch(formUpdateBatchDTO);
                // 保存日志
                saveLogger(formUpdateDTO.getLoginUser(), corpid, formUpdateDTO.getHttpHeader(), updateList);
            }
        }

    }

    private void saveLogger(UserVO userVO, String corpid, String httpHeader, List<FormEntityUpdateDTO> updateList) {
        // 记录日志
        Runnable runnable = () -> {
            try {
                for (FormEntityUpdateDTO item : updateList) {
                    List<String> nameList = new ArrayList<>();
                    item.getAssociationList().forEach(form->{
                        nameList.add(form.getName());
                    });
                    String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_FORM_ASSOCIATION_LIST), userVO.getName(), item.getName(), StringUtils.join(nameList, "、"));
                    mongoLogHelp.buildLog(corpid, userVO.getUserId(), userVO.getName(), OperateModuleTypeEnum.PAAS_FORM, OperateTypeEnum.EDIT,
                            item.getId().toString(), item.getName(), memo, httpHeader);
                }

            } catch (Exception e) {
                LOG.error("com.xbongbong.paas.service.impl.PaasFormServiceImpl.saveLogger fail", e);
            }
        };
        logThreadPoolBeanConfig.sysLogThreadPool().execute(runnable);
    }

    private List<FormEntityUpdateDTO> getUpdateFormList(List<PaasFormEntityExt> formList, PaasFormEntity paasFormEntity, Map<Long, List<RelatedLinkInfoPojo>> addLinkListPojoMap) {
        List<FormEntityUpdateDTO> updateList = new ArrayList<>();
        Map<String, LinkListPojo> linkListPojoMap = new HashMap<>(formList.size());
        Map<String, LinkListPojo> workOrderLinkListPojoMap = new HashMap<>(formList.size());
        for (PaasFormEntityExt item : formList) {
            List<LinkListPojo> linkListPojos = JSON.parseArray(item.getAssociationList(), LinkListPojo.class);
            if (Objects.isNull(linkListPojos)) {
                linkListPojos = new ArrayList<>();
            }
            linkListPojos.forEach(linkListPojo -> {
                if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), linkListPojo.getLinkBusinessType())) {
                    workOrderLinkListPojoMap.put(linkListPojo.getLinkFormId() + linkListPojo.getAttr(), linkListPojo);
                } else {
                    linkListPojoMap.put(linkListPojo.getLinkFormId() + linkListPojo.getAttr(), linkListPojo);
                }
            });
        }
        Integer num = getAssociationListMaxNum(paasFormEntity.getCorpid());
        for (PaasFormEntityExt item : formList) {
            FormEntityUpdateDTO formEntityUpdateDTO = new FormEntityUpdateDTO();
            List<LinkListPojo> linkListPojos = JSON.parseArray(item.getAssociationList(), LinkListPojo.class);
            if (Objects.isNull(linkListPojos)) {
                linkListPojos = new ArrayList<>();
            }

            if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), paasFormEntity.getBusinessType())) {
                List<RelatedLinkInfoPojo> list = addLinkListPojoMap.get(item.getId());
                for (RelatedLinkInfoPojo relatedLinkInfoPojo : list) {
                    if (!workOrderLinkListPojoMap.containsKey(paasFormEntity.getId() + relatedLinkInfoPojo.getAttr())) {
                        LinkListPojo linkListPojo = new LinkListPojo();
                        linkListPojo.setLinkAppId(paasFormEntity.getAppId());
                        linkListPojo.setLinkFormId(paasFormEntity.getId());
                        linkListPojo.setLinkMenuId(paasFormEntity.getMenuId());
                        linkListPojo.setLinkBusinessType(paasFormEntity.getBusinessType());
                        linkListPojo.setLinkSaasMark(paasFormEntity.getSaasMark());
                        linkListPojo.setName(paasFormEntity.getName());
                        linkListPojo.setAttr(relatedLinkInfoPojo.getAttr());
                        linkListPojo.setEnable(0);
                        linkListPojos.add(linkListPojo);
                    }
                }
            } else {
                List<RelatedLinkInfoPojo> list = addLinkListPojoMap.get(item.getId());
                for (RelatedLinkInfoPojo relatedLinkInfoPojo : list) {
                    if (!linkListPojoMap.containsKey(paasFormEntity.getId()+ relatedLinkInfoPojo.getAttr())) {
                        LinkListPojo linkListPojo = new LinkListPojo();
                        linkListPojo.setLinkAppId(paasFormEntity.getAppId());
                        linkListPojo.setLinkFormId(paasFormEntity.getId());
                        linkListPojo.setLinkMenuId(paasFormEntity.getMenuId());
                        linkListPojo.setLinkBusinessType(paasFormEntity.getBusinessType());
                        linkListPojo.setLinkSaasMark(paasFormEntity.getSaasMark());
                        linkListPojo.setName(paasFormEntity.getName());
                        linkListPojo.setAttr(relatedLinkInfoPojo.getAttr());
                        linkListPojo.setEnable(0);
                        linkListPojos.add(linkListPojo);
                    }
                }
            }
            if (linkListPojos.size() > num) {
                linkListPojos = linkListPojos.subList(0, num);
            }
            formEntityUpdateDTO.setAssociationList(linkListPojos);
            formEntityUpdateDTO.setId(item.getId());
            formEntityUpdateDTO.setName(item.getName());
            updateList.add(formEntityUpdateDTO);
        }

        return updateList;
    }

    /**
     * 需要删除的关联列表选项
     * @param formUpdateDTO
     * @param deleteLinkInfoList 需要删除的关联列表选项
     * @param paasFormEntity
     * @throws XbbException
     */
    private void deleteAssociationList(FormUpdateDTO formUpdateDTO, List<RelatedLinkInfoPojo> deleteLinkInfoList, PaasFormEntity paasFormEntity) throws XbbException {
        if (deleteLinkInfoList.isEmpty()) {
            return;
        }
        List<Long> deleteFormId = new ArrayList<>();
        List<Long> deleteWorkOrderFormId = new ArrayList<>();
        deleteLinkInfoList.forEach(item->{
            if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), item.getLinkBusinessType())) {
                deleteWorkOrderFormId.add(item.getLinkFormId());
            } else {
                deleteFormId.add(item.getLinkFormId());
            }
        });
        if (!deleteWorkOrderFormId.isEmpty()) {
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", paasFormEntity.getCorpid());
            param.put("del", DelEnum.NORMAL.getDel());
            param.put("idIn", deleteWorkOrderFormId);
            List<WorkOrderFormEntity> workOrderFormList = workOrderFormModel.findEntitys(param);
            if (Objects.isNull(workOrderFormList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
            List<PaasFormEntityExt> formList = new ArrayList<>();
            try {
                BeanUtil.copyPropertiesList(workOrderFormList, formList, PaasFormEntityExt.class);
            }catch (Exception e) {
                LOG.error("formServeice.deleteAssociationList 拷贝出错", e);
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
            FormUpdateBatchDTO formUpdateBatchDTO = new FormUpdateBatchDTO();
            BeanUtil.copyProperties(formUpdateDTO, formUpdateBatchDTO);
            List<FormEntityUpdateDTO> updateList = getDeleteAssociationFormList(formList, paasFormEntity);

            if (!updateList.isEmpty()) {
                formUpdateBatchDTO.setFormList(updateList);
                workOrderFormService.updateBatch(formUpdateBatchDTO);
            }
        }
        if (!deleteFormId.isEmpty()) {
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", paasFormEntity.getCorpid());
            param.put("del", DelEnum.NORMAL.getDel());
            param.put("idIn", deleteFormId);
            List<PaasFormEntityExt> formList = paasFormModel.list(param);
            if (Objects.isNull(formList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
            FormUpdateBatchDTO formUpdateBatchDTO = new FormUpdateBatchDTO();
            BeanUtil.copyProperties(formUpdateDTO, formUpdateBatchDTO);
            List<FormEntityUpdateDTO> updateList = getDeleteAssociationFormList(formList, paasFormEntity);
            if (!updateList.isEmpty()) {
                formUpdateBatchDTO.setFormList(updateList);
                updateBatch(formUpdateBatchDTO);
            }
        }
    }

    /**
     * 删除关联列表
     * @param formList
     * @param paasFormEntity
     * @return
     */
    private List<FormEntityUpdateDTO> getDeleteAssociationFormList(List<PaasFormEntityExt> formList, PaasFormEntity paasFormEntity) {
        List<FormEntityUpdateDTO> updateList = new ArrayList<>();
        formList.forEach(item->{
            FormEntityUpdateDTO formEntityUpdateDTO = new FormEntityUpdateDTO();
            List<LinkListPojo> linkLists = JSON.parseArray(item.getAssociationList(), LinkListPojo.class);
            Iterator<LinkListPojo> iterator = linkLists.iterator();
            while (iterator.hasNext()) {
                LinkListPojo linkListPojo = iterator.next();
                if (Objects.isNull(linkListPojo) || Objects.isNull(linkListPojo.getLinkFormId())) {
                    iterator.remove();
                    continue;
                }
                if (Objects.nonNull(linkListPojo.getLinkFormId()) && Objects.equals(paasFormEntity.getId(), linkListPojo.getLinkFormId())) {
                    iterator.remove();
                    continue;
                }
            }
            formEntityUpdateDTO.setAssociationList(linkLists);
            formEntityUpdateDTO.setId(item.getId());
            updateList.add(formEntityUpdateDTO);
        });
        return updateList;
    }




    private Map<String, FieldAttrEntity> linkMap(List<FieldAttrEntity> explainList) {
        Map<String, FieldAttrEntity> explainMap = new HashMap<>(explainList.size());
        explainList.forEach(item->{
            if (FieldTypeEnum.LINK_DATA.getType().equals(item.getFieldType()) || FieldTypeEnum.LINK_DATA_MULTI.getType().equals(item.getFieldType())) {
                explainMap.put(item.getAttr(), item);
            } else if (FieldTypeEnum.SUB_FORM.getType().equals(item.getFieldType())) {
                List<? extends FieldAttrEntity> subExplainList = item.getSubForm().getItems();
                subExplainList.forEach(subItem->{
                    if (FieldTypeEnum.LINK_DATA.getType().equals(subItem.getFieldType()) || FieldTypeEnum.LINK_DATA_MULTI.getType().equals(subItem.getFieldType())) {
                        if (subItem.getAttr().contains(FieldTypeEnum.SUB_FORM.getEsalias())) {
                            // 上面那个getAddAttrList方法，将新的explain重新设置了attr导致数据不对，所以这里做了兼容
                            explainMap.put(subItem.getAttr(), subItem);
                        } else {
                            explainMap.put(item.getAttr()+"."+subItem.getAttr(), subItem);
                        }
                    }
                });
            }
        });
        return explainMap;
    }
    /**
     * 校验attr规则
     * @param formUpdateDTO
     * @throws XbbException
     */
    private void validateAttrRule(FormUpdateDTO formUpdateDTO) throws XbbException{
        try {
            String corpid = formUpdateDTO.getCorpid();
            List<FieldAttrEntity> list = formUpdateDTO.getExplainList();
            HashSet<String> hashSet = new HashSet<>();
            HashSet<String> nameHashSet = new HashSet<>();
            LinkDataNumCheckPojo linkDataNumCheckPojo = new LinkDataNumCheckPojo();
            Integer saasMark = formUpdateDTO.getFormAttr().getSaasMark();
            Integer businessType = formUpdateDTO.getFormAttr().getBusinessType();
            //负责人唯一的时候，只允许添加一个默认值
            for (FieldAttrEntity fieldAttrEntity : list) {
                if(Objects.equals(fieldAttrEntity.getAttr(), FieldTypeEnum.OWNERID.getAlias())){
                    if(!Objects.equals(fieldAttrEntity.getMultiple(), Constant.ONE)
                            && Objects.equals(fieldAttrEntity.getDefaultAttr().getDefaultType(), DefaultTypeEnum.CUSTOM.getAlias())
                            && org.apache.commons.collections4.CollectionUtils.isNotEmpty(fieldAttrEntity.getDefaultAttr().getDefaultList())
                            && fieldAttrEntity.getDefaultAttr().getDefaultList().size() > Constant.ONE){
                        throw new XbbException(UserTeamErrorCodeEnum.API_ERROR_271035, UserTeamErrorCodeEnum.API_ERROR_271035.getMsg());
                    }
                }
            }

            if (Objects.equals(SaasMarkEnum.PAAS.getCode(), saasMark)) {
                businessType = XbbRefTypeEnum.PAAS.getCode();
            }
            ProEsAliasEnum proEsAliasEnum = ProEsAliasEnum.getByCode(String.valueOf(businessType));
            Integer feeType = businessRuleUserPermissionHelp.getFeeType(corpid);
            String configValue = companyConfigModel.getByConfigAlias(CompanyConfigEnum.ELASTICSEARCH_INDEX.getAlias(), CompanyConfigEnum.ELASTICSEARCH_INDEX.getAlias(), "0", "0", RedisTimeConstant.TEN_MINUTES);
            Set<String> corpidSet = new HashSet<>();
            if (StringUtil.isNotEmpty(configValue)) {
                corpidSet = new HashSet<>(JSON.parseArray(configValue, String.class));
            }
            Integer subFormSize = 0;
            for (FieldAttrEntity fieldAttrEntity: list) {
                String attr = fieldAttrEntity.getAttr();
                String attrName = fieldAttrEntity.getAttrName().trim();
                String attrNameEn = attrName;
                if (StringUtil.isNotEmpty(fieldAttrEntity.getAttrNameEn())) {
                    attrNameEn = fieldAttrEntity.getAttrNameEn().trim();
                }
                String realAttrName = "";
                if (Objects.equals(LocaleContextHolder.getLocale().getLanguage(), I18nStringConstant.ENGLISH_LANGUAGE)) {
                    realAttrName = attrNameEn;
                    fieldAttrEntity.setAttrName(attrNameEn);
                    fieldAttrEntity.setAttrNameEn(attrName);
                } else {
                    realAttrName = attrName;
                    fieldAttrEntity.setAttrName(attrName);
                    fieldAttrEntity.setAttrNameEn(attrNameEn);
                }
                Integer fieldType = fieldAttrEntity.getFieldType();
                if (StringUtil.isEmpty(attrName)
                        && !Objects.equals(FieldTypeEnum.MEMO.getType(), fieldType) && !Objects.equals(FieldTypeEnum.SEPARATOR.getType(), fieldType)) {
                    throw new XbbException(ProErrorCodeEnum.API_ERROR_260000);
                }
                if (ExplainUtil.isSubForm(fieldType)) {
                    subFormSize++;
                }
                FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldType);
                if(nameHashSet.contains(realAttrName) && StringUtil.isNotEmpty(fieldAttrEntity.getAttrName()) && !Objects.equals(fieldAttrEntity.getEditHide(), 1)){
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.ATTR_NAME_DUPLICATE, realAttrName);
                }else{
                    nameHashSet.add(realAttrName);
                }

                // 是否有工作报告批阅人(attr:array_3，字段类型改为text)
                boolean isReviewer = (Objects.equals(XbbRefTypeEnum.WORKREPORT_DAILY.getCode(), formUpdateDTO.getBusinessType())
                        || Objects.equals(XbbRefTypeEnum.WORKREPORT_WEEKLY.getCode(), formUpdateDTO.getBusinessType())
                        || Objects.equals(XbbRefTypeEnum.WORKREPORT_MONTHLY.getCode(), formUpdateDTO.getBusinessType())) &&
                        Objects.equals(WorkReportFieldEnum.REVIEWER.getAttr(), attr);

                // 校验attr没有下划线，提示参数异常
                if(!FieldTypeEnum.CREATORID.getType().equals(fieldType) && !FieldTypeEnum.ADDTIME.getType().equals(fieldType)
                        && !FieldTypeEnum.UPDATETIME.getType().equals(fieldType) && !FieldTypeEnum.DEPARTMENTID.getType().equals(fieldType)
                        && !FieldTypeEnum.OWNERID.getType().equals(fieldType) && !FieldTypeEnum.COUSERID.getType().equals(fieldType)
                        && !FieldTypeEnum.SERIALNO.getType().equals(fieldType) && !FieldTypeEnum.CONTACT_NUMBER.getType().equals(fieldType)
                        && !FieldTypeEnum.SEPARATOR.getType().equals(fieldType) && !FieldTypeEnum.WORK_ORDER_STATUS.getType().equals(fieldType)
                        && !FieldTypeEnum.WORK_ORDER_ALL_OUTBOUND.getType().equals(fieldType) && !FieldTypeEnum.STAR.getType().equals(fieldType)
                        && !FieldTypeEnum.WORK_ORDER_STAGE.getType().equals(fieldType) && !FieldTypeEnum.ENDTIME.getType().equals(fieldType)
                        && !FieldTypeEnum.CLOSETIME.getType().equals(fieldType) && !FieldTypeEnum.WORK_ORDER_NODE_STATUS.getType().equals(fieldType)
                        && !FieldTypeEnum.WORK_ORDER_STAGE_NAME.getType().equals(fieldType)
                        && !CustomerManagementEnum.CONTRACT_SIGN_DATE.getAttr().equals(attr)
                        && !CustomerManagementEnum.OPPORTUNITY_ADD_DATE.getAttr().equals(attr)) {
                    if (!attr.contains("_")) {
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028, MessageConstant.ABNORMAL_PARAMETER, attrName);
                    }
                    String[] attrArray = fieldAttrEntity.getAttr().split("_");
                    String attrAlias = attrArray[0];
                    Integer esAliasLength= Integer.valueOf(attrArray[1]);
                    // 校验es
                    validateFieldEsAlias(attrAlias, fieldTypeEnum.getEsalias(), isReviewer, attrName);
                    if (Objects.equals(attrAlias, EsAliasEnum.TEXT.getEsAlias()) && corpidSet.contains(corpid) && Objects.equals(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), businessType) && Objects.equals(DistributorMarkEnum.OTHER.getCode(), formUpdateDTO.getFormAttr().getDistributorMark())) {
                        boolean over = (esAliasLength > proEsAliasEnum.getTextMax() && esAliasLength < EsAliasEnum.TEXT.getSaasMax()) || esAliasLength > EsAliasEnum.TEXT.getSeparateIndexMax();
                        if (over)  {
                            // 字段数超过了规定阈值，按规定客户可拖到proEsAliasEnum.getTextMax()，以及101到130个文本字段，所以在proEsAliasEnum.getTextMax()到100，以及130以上不允许客户自定义
                            throw new XbbException(ProErrorCodeEnum.API_ERROR_260021, ProErrorCodeEnum.API_ERROR_260021.getMsg(), attrName);
                        }
                    } else {
                        // 校验长度
                        validateEsAliasLength(fieldTypeEnum, proEsAliasEnum, esAliasLength, isReviewer, attrName);
                    }

                }
                // 子表单解析
                if (ExplainUtil.isSubFormNoSelectProduct(fieldType)){
                    HashSet<String> subHashSet = new HashSet<>();
                    HashSet<String> subNameHashSet = new HashSet<>();
                    List<? extends FieldAttrEntity> subList = fieldAttrEntity.getSubForm().getItems();
                    if (Objects.isNull(subList) || subList.isEmpty()) {
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.SUB_FORM_NO_HAS_FIELD, attrName);
                    }
                    // 出库单不允许subForm_3的字段
                    List<Integer> blockList = Arrays.asList(XbbRefTypeEnum.OUTSTOCK.getCode(),XbbRefTypeEnum.RETURNED_PURCHASE_OUTSTOCK.getCode(), XbbRefTypeEnum.OTHER_OUTSTOCK.getCode(),
                            XbbRefTypeEnum.PRODUCTION_MATERIEL_OUTSTOCK.getCode());
                    if (blockList.contains(businessType) && Objects.equals(ContractOutstockEnum.CUSTOMER_PHONE.getAttr(), attr)) {
                        throw new XbbException(ProErrorCodeEnum.API_ERROR_500019, ProErrorCodeEnum.API_ERROR_500019.getMsg(), attrName);
                    }
                    ProEsAliasEnum subFormEsAliasEnum = ProEsAliasEnum.getByCode(String.valueOf(fieldType));
                    for (FieldAttrEntity subAttrEntity: subList) {
                        String subAttr = subAttrEntity.getAttr();
                        String subAttrName = subAttrEntity.getAttrName().trim();
                        String subAttrNameEn = subAttrName;
                        if (StringUtil.isNotEmpty(subAttrEntity.getAttrNameEn())) {
                            subAttrNameEn = subAttrEntity.getAttrNameEn().trim();
                        }
                        String realSubAttrName = "";
                        if (Objects.equals(LocaleContextHolder.getLocale().getLanguage(), I18nStringConstant.ENGLISH_LANGUAGE)) {
                            realSubAttrName = subAttrNameEn;
                            subAttrEntity.setAttrName(subAttrNameEn);
                            subAttrEntity.setAttrNameEn(subAttrName);
                        } else {
                            realSubAttrName = subAttrName;
                            subAttrEntity.setAttrName(subAttrName);
                            subAttrEntity.setAttrNameEn(subAttrNameEn);
                        }
                        if (StringUtil.isEmpty(subAttrName)) {
                            throw new XbbException(ProErrorCodeEnum.API_ERROR_500000);
                        }
                        String name = attrName+subAttrName;
                        // 校验主键字段
                        linkDataNumCheckPojo = validateLinkKey(subAttrEntity, name, linkDataNumCheckPojo);
                        if(subNameHashSet.contains(realSubAttrName) && !Objects.equals(fieldAttrEntity.getEditHide(), 1)){
                            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.ATTR_NAME_DUPLICATE, name);
                        }else{
                            subNameHashSet.add(realSubAttrName);
                        }
                        // 校验attr没有下划线，提示参数异常
                        if(StringUtil.isEmpty(subAttr) ||  !subAttr.contains("_")){
                            throw  new XbbException(SystemErrorCodeEnum.API_ERROR_100028, MessageConstant.ABNORMAL_PARAMETER, name);
                        }
                        validateComboType(subAttrEntity, name);
                        // 校验关联数据的条件数量
                        validateLinkInfoCondition(subAttrEntity, attrName);
                        String[] subAttrArray = subAttr.split("_");
                        Integer subFieldType = subAttrEntity.getFieldType();
                        fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(subFieldType);
                        // 校验es的alias
                        validateFieldEsAlias(subAttrArray[0], fieldTypeEnum.getEsalias(), isReviewer, attrName);
                        // 校验es字段长度
                        validateEsAliasLength(fieldTypeEnum, subFormEsAliasEnum, Integer.parseInt(subAttrArray[1]) , isReviewer, name);
                        subHashSet.add(subAttr);
                    }
                    if(subHashSet.size() != subList.size()){
                        throw  new XbbException(SystemErrorCodeEnum.API_ERROR_100028, MessageConstant.FORM_DESIGN_DUPLICATE_VALUE);
                    }
                } else if (FieldTypeEnum.SELECT_PRODUCT.getType().equals(fieldType)) {
//                    List<FieldAttrEntity> subFieldAttrs = fieldAttrEntity.getSubForm().getItems().toJavaList(FieldAttrEntity.class);
                    SubFormPoJo subForm = fieldAttrEntity.getSubForm();
                    Set<String> subNameHashSet = new HashSet<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    if (subForm != null && subForm.getItems() != null) {
                        List<? extends FieldAttrEntity> subFieldAttrs = subForm.getItems();
                        // 子表单的限制
                        // 采购合同产品新增text_22只显示合同编号
                        String code = businessType + "_" + FieldTypeEnum.SELECT_PRODUCT.getType();
                        ProEsAliasEnum subFormEsAliasEnum = ProEsAliasEnum.getSelectProductByCode(code);
                        for (FieldAttrEntity subFieldAttr : subFieldAttrs) {
                            String subAttrName = subFieldAttr.getAttrName().trim();
                            String subAttrNameEn = subAttrName;
                            if (StringUtil.isNotEmpty(subFieldAttr.getAttrNameEn())) {
                                subAttrNameEn = subFieldAttr.getAttrNameEn().trim();
                            }
                            String realSubAttrName = "";
                            if (Objects.equals(LocaleContextHolder.getLocale().getLanguage(), I18nStringConstant.ENGLISH_LANGUAGE)) {
                                realSubAttrName = subAttrNameEn;
                                subFieldAttr.setAttrName(subAttrNameEn);
                                subFieldAttr.setAttrNameEn(subAttrName);
                            } else {
                                realSubAttrName = subAttrName;
                                subFieldAttr.setAttrName(subAttrName);
                                subFieldAttr.setAttrNameEn(subAttrNameEn);
                            }
                            if (StringUtil.isEmpty(subAttrName)) {
                                // bug-id: 28662
                                throw new XbbException(ProErrorCodeEnum.API_ERROR_500000);
                            }
                            String subAttr = subFieldAttr.getAttr();
                            String name = attrName + subAttrName;
                            String[] subAttrArray = subAttr.split("_");
                            Integer subFieldType = subFieldAttr.getFieldType();
                            // 数据联动设置校验
                            validateComboType(subFieldAttr, name);
                            // 校验关联数据的条件数量
                            validateLinkInfoCondition(subFieldAttr, name);
                            fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(subFieldType);
                            //TODO 校验es的alias
                            // 校验es字段长度
                            validateEsAliasLength(fieldTypeEnum, subFormEsAliasEnum, Integer.parseInt(subAttrArray[1]) , isReviewer, name);
                            // 校验主键字段
                            linkDataNumCheckPojo = validateLinkKey(subFieldAttr, name, linkDataNumCheckPojo);
                            if(subNameHashSet.contains(realSubAttrName) && !Objects.equals(fieldAttrEntity.getEditHide(), 1)){
                                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.ATTR_NAME_DUPLICATE, name);
                            }else{
                                subNameHashSet.add(realSubAttrName);
                            }
                        }
                    }
                }
                // 数据联动设置校验
                validateComboType(fieldAttrEntity, attrName);
                linkDataNumCheckPojo = validateLinkKey(fieldAttrEntity, attrName, linkDataNumCheckPojo);
                // 校验关联数据的条件数量
                validateLinkInfoCondition(fieldAttrEntity, attrName);
                hashSet.add(attr);
                //客户线索需要对自定义字段全局判重配置校验
                if (Objects.equals(businessType, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.CLUE.getCode())) {
                    if (Objects.equals(PackageTypeEnum.ULTIMATE.getType(),feeType)) {
                        validateCustomRecheckRules(fieldAttrEntity);
                    }
                }
            }

            if (Objects.equals(businessType, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.CLUE.getCode())) {
                PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(formUpdateDTO.getFormId(), formUpdateDTO.getCorpid());
                List<FieldAttrEntity> explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
                // 原表单中explainList中不允许重复值个数
                Integer dbNoRepeatCount = getNoRepeatCount(explainList,businessType,formUpdateDTO.getFormId(),formUpdateDTO.getCorpid());
                //当前编辑表单解析中不允许重复值个数
                Integer editNoRepeatCount = getNoRepeatCount(list,businessType,formUpdateDTO.getFormId(),formUpdateDTO.getCorpid());
                //编辑保存的时候判断不允许重复的字段个数小于等于上一次保存时候的个数,或者小于等于3
                if (!(editNoRepeatCount <= dbNoRepeatCount || editNoRepeatCount <= BasicConstant.THREE)) {
                    throw new XbbException(ProErrorCodeEnum.API_ERROR_260052);
                }
            }

            if(hashSet.size() != list.size()){
                throw  new XbbException(SystemErrorCodeEnum.API_ERROR_100028, MessageConstant.FORM_DESIGN_DUPLICATE_VALUE);
            }
            // 关联数据子表单外和子表单内总数不超过12个
            if (linkDataNumCheckPojo.getLinkDataNum() > PaasConstant.LINK_DATA_NUM) {
                throw new XbbException(ProErrorCodeEnum.API_ERROR_500017, ProErrorCodeEnum.API_ERROR_500017.getMsg(), FieldTypeEnum.LINK_DATA.getDescription());
            }
            if (linkDataNumCheckPojo.getLinkDataMultiNum() > PaasConstant.LINK_DATA_MULTI_NUM) {
                throw new XbbException(ProErrorCodeEnum.API_ERROR_500017, ProErrorCodeEnum.API_ERROR_500017.getMsg(), FieldTypeEnum.LINK_DATA_MULTI.getDescription());
            }
            if (subFormSize> EsAliasEnum.SUB_FORM.getMax()+1) {
                // 原因子表单的数量是8个（自定义子表单+关联产品），但是由于客户已有8个自定义子表单，所以这边对关联产品进行+1，共9个；
                throw new XbbException(ProErrorCodeEnum.API_ERROR_500017, ProErrorCodeEnum.API_ERROR_500017.getMsg(), FieldTypeEnum.SUB_FORM.getDescription());
            }
        }catch (XbbException e) {
            throw e;
        }catch (Exception e) {
            LOG.error("校验索引规则报错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    private Integer getNoRepeatCount(List<FieldAttrEntity> explainList,Integer businessType, Long formId, String corpid) {
        Integer noRepeatCount = 0;
        String nameConfig = FormConfigEnum.CUSTOMER_NAME_REPEAT_TYPE.getConfig();
        String phoneConfig = FormConfigEnum.CUSTOMER_PHONE_REPEAT_TYPE.getConfig();
        if (Objects.equals(businessType, XbbRefTypeEnum.CLUE.getCode())) {
            nameConfig = FormConfigEnum.CLUE_NAME_REPEAT_TYPE.getConfig();
            phoneConfig = FormConfigEnum.CLUE_PHONE_REPEAT_TYPE.getConfig();
        }

        FormConfigEntity nameConfigEntity = formConfigModel.getEntityByFormId(corpid, formId, nameConfig);
        FormConfigEntity phoneConfigEntity = formConfigModel.getEntityByFormId(corpid, formId, phoneConfig);
        for (FieldAttrEntity fieldAttrEntity : explainList) {
            if (Objects.equals(fieldAttrEntity.getIsOpen(),BasicConstant.ONE) && !(Objects.nonNull(fieldAttrEntity.getEditHide()) && Objects.equals(fieldAttrEntity.getEditHide(),BasicConstant.ONE))) {
                if (Objects.equals(fieldAttrEntity.getFieldType(),FieldTypeEnum.SUB_FORM.getType()) || Objects.equals(fieldAttrEntity.getFieldType(),FieldTypeEnum.CONTACT_NUMBER.getType())) {
                    if (Objects.nonNull(fieldAttrEntity.getSubForm()) && CollectionsUtil.isNotEmpty(fieldAttrEntity.getSubForm().getItems())) {
                        List<? extends FieldAttrEntity> items = fieldAttrEntity.getSubForm().getItems();
                        if (Objects.equals(fieldAttrEntity.getAttr(),"subForm_1")) {
                            //特殊判断电话字段
                            for (FieldAttrEntity item : items) {
                                if (Objects.equals(item.getAttr(),"text_2")) {
                                    if (Objects.nonNull(phoneConfigEntity) && !Objects.equals(phoneConfigEntity.getConfigValue(),RepeatTypeEnum.REPEAT_CANCEL.getType().toString())) {
                                        noRepeatCount ++;
                                    } else {
                                        if (Objects.equals(item.getNoRepeat(),BasicConstant.ONE)) {
                                            noRepeatCount ++;
                                        }
                                    }
                                }
                            }
                        } else {
                            for (FieldAttrEntity item : items) {
                                if (!(Objects.nonNull(item.getEditHide()) && Objects.equals(item.getEditHide(),BasicConstant.ONE)) && Objects.equals(item.getIsOpen(),BasicConstant.ONE) && Objects.nonNull(item.getNoRepeat()) && Objects.equals(item.getNoRepeat(),BasicConstant.ONE)) {
                                    noRepeatCount ++;
                                }
                            }
                        }
                    }
                } else {
                    if (Objects.equals(fieldAttrEntity.getAttr(),"text_1")) {
                        if (Objects.nonNull(nameConfigEntity) && !Objects.equals(nameConfigEntity.getConfigValue(),RepeatTypeEnum.REPEAT_CANCEL.getType().toString())) {
                            noRepeatCount ++;
                        } else {
                            if (Objects.equals(fieldAttrEntity.getNoRepeat(),BasicConstant.ONE)) {
                                noRepeatCount ++;
                            }
                        }
                    } else {
                        if (!(Objects.nonNull(fieldAttrEntity.getEditHide()) && Objects.equals(fieldAttrEntity.getEditHide(),BasicConstant.ONE)) && Objects.equals(fieldAttrEntity.getIsOpen(),BasicConstant.ONE) && Objects.nonNull(fieldAttrEntity.getNoRepeat()) && Objects.equals(fieldAttrEntity.getNoRepeat(),BasicConstant.ONE)) {
                            noRepeatCount ++;
                        }
                    }
                }
            }
        }


//        List<FieldAttrEntity> fieldAttrEntityList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
//        //获取表单解析包含子表单中启用并未隐藏的字段
//        for (FieldAttrEntity fieldAttrEntity : explainList) {
//            if (Objects.equals(fieldAttrEntity.getIsOpen(),BasicConstant.ONE) && !(Objects.nonNull(fieldAttrEntity.getEditHide()) && Objects.equals(fieldAttrEntity.getEditHide(),BasicConstant.ONE))) {
//                if (Objects.equals(fieldAttrEntity.getFieldType(),FieldTypeEnum.SUB_FORM.getType()) || Objects.equals(fieldAttrEntity.getFieldType(),FieldTypeEnum.CONTACT_NUMBER.getType())) {
//                    if (Objects.nonNull(fieldAttrEntity.getSubForm()) && CollectionsUtil.isNotEmpty(fieldAttrEntity.getSubForm().getItems())) {
//                        List<FieldAttrEntity> entityList = (List<FieldAttrEntity>) fieldAttrEntity.getSubForm().getItems();
//                        fieldAttrEntityList.addAll(entityList);
//                    }
//                } else {
//                    fieldAttrEntityList.add(fieldAttrEntity);
//                }
//            }
//        }
//
//        for (FieldAttrEntity attrEntity : fieldAttrEntityList) {
//            if (Objects.equals(attrEntity.getEditHide(),BasicConstant.ZERO) && Objects.equals(attrEntity.getIsOpen(),BasicConstant.ONE) && Objects.nonNull(attrEntity.getNoRepeat()) && Objects.equals(attrEntity.getNoRepeat(),BasicConstant.ONE)) {
//                noRepeatCount ++;
//            }
//        }
        return noRepeatCount;
    }

    private void validateCustomRecheckRules(FieldAttrEntity fieldAttrEntity) throws XbbException {
        List<FieldAttrEntity> entitieList = new ArrayList<>();
        if (Objects.equals(fieldAttrEntity.getIsOpen(),BasicConstant.ONE) && !(Objects.nonNull(fieldAttrEntity.getEditHide()) && Objects.equals(fieldAttrEntity.getEditHide(),BasicConstant.ONE))) {
            if (Objects.equals(fieldAttrEntity.getFieldType(),FieldTypeEnum.SUB_FORM.getType()) || Objects.equals(fieldAttrEntity.getFieldType(),FieldTypeEnum.CONTACT_NUMBER.getType())) {
                if (Objects.nonNull(fieldAttrEntity.getSubForm()) && CollectionsUtil.isNotEmpty(fieldAttrEntity.getSubForm().getItems())) {
                    entitieList = (List<FieldAttrEntity>) fieldAttrEntity.getSubForm().getItems();
                }
            } else {
                entitieList.add(fieldAttrEntity);
            }
        }

        for (FieldAttrEntity attrEntity : entitieList) {
            if (Objects.equals(attrEntity.getIsOpen(),BasicConstant.ONE) && Objects.equals(attrEntity.getNoRepeat(),BasicConstant.ONE)) {
                if (Objects.equals(attrEntity.getCustomRepeatType(),BasicConstant.TWO) && CollectionsUtil.isEmpty(attrEntity.getCustomRecheckRules())) {
                    throw new XbbException(ProErrorCodeEnum.API_ERROR_260053, ProErrorCodeEnum.API_ERROR_260053.getMsg(), attrEntity.getAttrName());
                }
                if (CollectionsUtil.isNotEmpty(attrEntity.getCustomRecheckRules())) {
                    List<CustomRecheckRulePojo> customRecheckRules = attrEntity.getCustomRecheckRules();
                    Set set = new HashSet();
                    customRecheckRules.forEach(item -> set.add(item.getFormId()));
                    if (customRecheckRules.size() != set.size())
                        throw new XbbException(ProErrorCodeEnum.API_ERROR_260051);
                }
            }
        }
    }

    @Override
    public FieldTypeListVO fieldTypeList(FieldTypeListDTO fieldTypeListDTO) throws XbbException {
        FieldTypeListVO fieldTypeListVO = new FieldTypeListVO();
        try {
            List<Map<String, Object>> list = new ArrayList<>();
            List<Map<String, Object>> list1 = new ArrayList<>();
            List<Map<String, Object>> list2 = new ArrayList<>();
            List<Map<String, Object>> list3 = new ArrayList<>();
            for (FieldTypeEnum e: FieldTypeEnum.values()) {
                Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                if ("basic".equals(e.getBelong())) {
                    map.put("alias", e.getAlias());
                    map.put("type", e.getType());
                    map.put("description", e.getDescription());
                    map.put("belong", e.getBelong());
                    list1.add(map);
                }
                if ("complex".equals(e.getBelong())) {
                    map.put("alias", e.getAlias());
                    map.put("type", e.getType());
                    map.put("description", e.getDescription());
                    map.put("belong", e.getBelong());
                    list2.add(map);
                }
                if ("system".equals(e.getBelong())) {
                    map.put("alias", e.getAlias());
                    map.put("type", e.getType());
                    map.put("description", e.getDescription());
                    map.put("belong", e.getBelong());
                    list3.add(map);
                }
            }
            Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            map.put("className", "basic");
            map.put("fieldTypes", list1);
            list.add(map);
            map.put("className", "complex");
            map.put("fieldTypes", list2);
            list.add(map);
            map.put("className", "system");
            map.put("fieldTypes", list3);
            list.add(map);
            fieldTypeListVO.setFieldTypeList(list);
        } catch (Exception e) {
            LOG.error("fieldTypeList数据库查询出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return fieldTypeListVO;
    }

    @Override
    public CoUserPermissionListVO synergeticList(CoUserPermissionListDTO coUserListDTO) throws XbbException {
        CoUserPermissionListVO synergeticListVO = new CoUserPermissionListVO();
        try {
            Map<String, Object> param = BeanUtil.convertBean2Map(coUserListDTO, true);
            List<PaasFormEntityExt> formList = paasFormModel.list(param);
            if (formList == null || formList.isEmpty() ) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
            }
            PaasFormEntityExt paasFormEntityExt = formList.get(0);
            synergeticListVO.setAppId(paasFormEntityExt.getAppId());
            synergeticListVO.setFormId(paasFormEntityExt.getId());
            synergeticListVO.setCoOpPerms(JSON.parseObject(paasFormEntityExt.getCoOpPerms(), CoOpPermsEntityExt.class));
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("synergeticList数据库查询出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return synergeticListVO;
    }

    @Override
    public CoUserPermissionUpdateVO synergeticUpdate(CoUserPermissionUpdateDTO synergeticUpdateDTO) throws XbbException {
        CoUserPermissionUpdateVO synergeticUpdateVO = new CoUserPermissionUpdateVO();
        PaasFormEntity paasFormEntity = new PaasFormEntity();

        paasFormEntity.setCorpid(synergeticUpdateDTO.getCorpid());
        paasFormEntity.setCoOpPerms(JSONObject.toJSONString(synergeticUpdateDTO.getCoOpPerms()));
        String corpid = synergeticUpdateDTO.getCorpid();
        String userId = synergeticUpdateDTO.getUserId();
        String userName = synergeticUpdateDTO.getLoginUserName();
        try {
            Map<String, Object> param = BeanUtil.convertBean2Map(synergeticUpdateDTO, true);
            List<PaasFormEntityExt> formList = paasFormModel.list(param);
            if (formList == null || formList.isEmpty() ) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
            }
            PaasFormEntityExt paasFormEntityExt = formList.get(0);
            paasFormEntity.setId(paasFormEntityExt.getId());
            paasFormModel.update(paasFormEntity);

            synergeticUpdateVO.setAppId(synergeticUpdateDTO.getAppId());
            synergeticUpdateVO.setFormId(paasFormEntityExt.getId());
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("synergeticUpdate数据库更新出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        // 记录日志
        String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_UPDATE_FORM_CO_OP_PERMS), userName, paasFormEntity.getName());
        mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.PAAS_FORM, OperateTypeEnum.EDIT,
                paasFormEntity.getId().toString(), paasFormEntity.getName(), memo, synergeticUpdateDTO.getHttpHeader());

        return synergeticUpdateVO;
    }

    public FormListVO getformList(FormListDTO formListDTO) throws  XbbException {
        FormListVO formListVO = new FormListVO();
        try {
            Map<String, Object> map = BeanUtil.convertBean2Map(formListDTO, true);
            List<PaasFormEntityExt> list = paasFormModel.list(map);
            if(list == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_FORM_NOT_EXIST);
            }
            formListVO.setFormList(list);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasFormService数据库查询表单出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formListVO;
    }


    @Override
    public FormListVO formList(FormListDTO formListDTO) throws XbbException {
        FormListVO formListVO = new FormListVO();

        try {
            Map<String, Object> map = BeanUtil.convertBean2Map(formListDTO, true);
            // 菜单id为0为bi表单，无需搜出
            map.put("negMenuId", 0);
            List<PaasFormEntityExt> list = paasFormModel.list(map);
            if(list == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_FORM_NOT_EXIST);
            }
            List<Integer> invisible = Arrays.asList(XbbRefTypeEnum.STOCK_PRODUCT.getCode(), XbbRefTypeEnum.PREPAYMENT_BALANCE.getCode());
            if(formListDTO.getMenuId() != null){
                for (PaasFormEntityExt formEntityExt : list) {
                    if (Objects.equals(SaasMarkEnum.SAAS.getCode(), formEntityExt.getSaasMark())
                            && invisible.contains(formEntityExt.getBusinessType())){
                        continue;
                    }
                    // 过滤掉bi的一些表单
                    BIProductEnum biProductEnum = BIProductEnum.getByCode(formEntityExt.getBusinessType());
                    if (Objects.nonNull(biProductEnum) ||
                            Objects.equals(formEntityExt.getBusinessType(), XbbRefTypeEnum.CONTRACT_PERFORMANCE.getCode())) {
                        continue;
                    }
                    // 过滤掉周报，日报，月报
                    WorkReportEnum workReportEnum = WorkReportEnum.getByCode(formEntityExt.getBusinessType());
                    if (Objects.nonNull(workReportEnum)) {
                        continue;
                    }
                    if(formEntityExt.getId().equals(formListDTO.getFormId())){
                        list.remove(formEntityExt);
                        break;
                    }
                }
            }
            formListVO.setFormList(list);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasFormService数据库查询表单出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formListVO;
    }

    /**
     * 日志检索当前应用启用的菜单
     *
     * @param formListDTO
     * @return
     * @throws XbbException
     */
    @Override
    public MenuListVO logMenuList(FormListDTO formListDTO) throws XbbException {
        MenuListVO menuListVO = new MenuListVO();
        try {
            Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            map.put("corpid", formListDTO.getCorpid());
            map.put("enable", formListDTO.getEnable());
            map.put("appId", formListDTO.getAppId());
            map.put("del", formListDTO.getDel());
            List<PaasMenuEntityExt> menuList = paasMenuModel.getMenuList(map);
            if(menuList == null){
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.MENU_NOT_EXIST);
            }
            if(formListDTO.getMenuId() != null){
                for (PaasMenuEntityExt paasMenuEntityExt : menuList) {
                    if(paasMenuEntityExt.getId().equals(formListDTO.getFormId())){
                        menuList.remove(paasMenuEntityExt);
                        break;
                    }
                }
            }
            menuListVO.setMenuList(menuList);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasFormService数据库查询表单出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return menuListVO;
    }


    @Override
    public FormAllListVO getAllformList(FormAllListDTO formAllListDTO) throws XbbException {
       FormAllListVO  formAllListVO = new FormAllListVO();
        try {
            Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            params.put("corpid",formAllListDTO.getCorpid());
            params.put("del", DelEnum.NORMAL.getDel());
            List<Long> idList = formAllListDTO.getAppIdList();
            if(idList != null && !idList.isEmpty()){
                params.put("idIn", idList);
            }
            //  市场活动暂时过滤掉

            params.put("enable", 1);
            params.put("columns","id, corpid, name, name_en,alias");
            List<PaasAppEntity> appList = paasAppModel.findEntitys(params);
            //查不到应用直接返回
            if(appList == null || appList.isEmpty()) {
                List<FormResultListVO> resultList = new ArrayList<>();
                formAllListVO.setAppList(resultList);
                return formAllListVO;
            }
            Boolean pastDue = feeLogService.workOrderV2PastDue(formAllListDTO.getCorpid());
            if (pastDue) {
                appList.removeIf(app -> Objects.equals(XbbRefTypeEnum.WORK_ORDER_V2_CENTER.getAlias(), app.getAlias()));
            }
            List<Long> appIdList = new ArrayList<>();
            Long workOrderAppId = null;
            //经销商管理是否开启
            boolean distributorFlag = false;
            for (PaasAppEntity paasAppEntity : appList) {
                appIdList.add(paasAppEntity.getId());
                if (Objects.equals(paasAppEntity.getAlias(), XbbRefTypeEnum.WORK_ORDER.getAlias())) {
                    workOrderAppId = paasAppEntity.getId();
                }
                if (Objects.equals(paasAppEntity.getAlias(), XbbRefTypeEnum.DISTRIBUTOR.getAlias())) {
                    Integer feeType = packageHelp.getFeeType(formAllListDTO.getCorpid());
                    if (!Objects.equals(feeType, PackageTypeEnum.STANDARD.getType()) && (Objects.nonNull(paasAppEntity) && Objects.equals(paasAppEntity.getEnable(), BasicConstant.ONE))){
                        distributorFlag = true;
                    }
                }
            }
            formAllListDTO.setAppIdList(appIdList);
            List<Long>  selfList = new ArrayList<>();
            List<SelectedFormPojo> selectedFormList = formAllListDTO.getSelectedFormList();
            List<PaasFormEntityExt> formList = new ArrayList<>();
            Map<String, Object> map = BeanUtil.convertBean2Map(formAllListDTO, true);
            map.put("columns","id, corpid, name,app_id,saas_mark,menu_id,business_type");
            map.put("enable",1);
            //需要移除产品子表单主业务的业务code
            Integer removeProductMainFormBusiness = null;
            //需要移除产品子表单主业务的表单id,这个恶心的字段主要是为了经销商那边有用到
            Long removeMainFormId = null;
            PaasFormEntityExt removePaasFormEntityExt = new PaasFormEntityExt();
            boolean appNameShowTag = false;
            PaasFormEntityExt appNameShowTagFormEntityExt = new PaasFormEntityExt();
            if(CollectionsUtil.isNotEmpty(selectedFormList)){
                //这个参数只有在多表关联的时候才会选到，并且如果主表选择了产品子表单，就自动带出子表单关联的主业务表单
                for (int i=0;i<selectedFormList.size();i++){
                    SelectedFormPojo selectedFormPojo = selectedFormList.get(i);
                    selfList.add(selectedFormPojo.getFormId());
                }
                if (selectedFormList.size() == BasicConstant.ONE) {
                    SelectedFormPojo selectedFormPojo = selectedFormList.get(BasicConstant.ZERO);
                    //代表多表关联的情况下，并且选择了一个主表的情况。这时候可以根据子产品表去获取主表信息
                    PaasFormRefEntity paasFormRefEntity = paasFormRefModel.getMainFormIdByFormId(selectedFormPojo.getFormId(), formAllListDTO.getCorpid());
                    if (Objects.nonNull(paasFormRefEntity)) {
                        Long mainFormId = paasFormRefEntity.getMainFormId();
                        PaasFormEntityExt mainPaasForm = paasFormModel.getByKey(mainFormId, formAllListDTO.getCorpid());
                        if (Objects.equals(mainPaasForm.getEnable(), BasicConstant.ONE)) {
                            formList.add(mainPaasForm);
                        }else {
                            appNameShowTagFormEntityExt = mainPaasForm;
                            appNameShowTag = true;
                        }
                    }else {
                        formList = paasFormModel.list(map);
                    }
                }else {
                    for (SelectedFormPojo selectedFormPojo : selectedFormList) {
                        BIProductReformEnum biProductReformEnum = BIProductReformEnum.getEnumByProductBusinessType(selectedFormPojo.getBusinessType());
                        if (Objects.nonNull(biProductReformEnum)) {
                            removeProductMainFormBusiness = biProductReformEnum.getBusinessType();
                            break;
                        }
                    }
                    for (SelectedFormPojo selectedFormPojo : selectedFormList) {
                        if (Objects.nonNull(removeProductMainFormBusiness) && Objects.equals(selectedFormPojo.getBusinessType(), removeProductMainFormBusiness)) {
                            removeMainFormId = selectedFormPojo.getFormId();
                            break;
                        }
                    }
                    if (Objects.nonNull(removeMainFormId)) {
                        removePaasFormEntityExt = paasFormModel.getByKey(removeMainFormId, formAllListDTO.getCorpid());
                    }
                    formList = paasFormModel.list(map);
                }
            }else {
                formList = paasFormModel.list(map);
            }
            Map<Long, List<FormSimpleListVO>> menuMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            //多表的才会选中复数产品相关的  1单表，0多表
            Integer single = formAllListDTO.getSingle();
            boolean isDataSet = Objects.equals(BasicConstant.THREE, single);
            if(Objects.equals(1, single) || isDataSet){
                //存在工单中心时 添加工单列表页
                formList.addAll(getWorkOrderList(formAllListDTO.getCorpid(), workOrderAppId));
            }

            List<Integer> businessTypeList = IndexTypeEnum.getAllEnumCode();
            //加入产品的businessType    关联产品的暂时去除  和进销存同学已商定  2020年6月10日15:49:20
//            businessTypeList.addAll(BIProductEnum.getAllEnumCode());
            VerifyViewPermissionDTO verifyViewPermissionDTO = new VerifyViewPermissionDTO();
            BeanUtil.copyProperties(formAllListDTO, verifyViewPermissionDTO);
            //关联产品需求需要判断业务里面这个产品字段有没有开启
            List<PaasFormEntityExt> allBiProductPaasFormList = new ArrayList<>();
            List<Long> allBiProductPaasFormIdList = new ArrayList<>();
            List<Long> multipleBiProductPaasFormIdList = new ArrayList<>();
            Set<Integer> multipleProductCodeList = BIProductReformEnum.getMultipleProductCodeList();
            //多表、数据集都需要处理关联产品
            boolean linkProduct = Objects.equals(BasicConstant.ZERO, single) || ChartSourceEnum.isDataSet(single);
            for (PaasFormEntityExt paasFormEntityExt : formList) {
                verifyViewPermissionDTO.setSaasMark(paasFormEntityExt.getSaasMark());
                verifyViewPermissionDTO.setMenuId(paasFormEntityExt.getMenuId());
                verifyViewPermissionDTO.setBusinessType(paasFormEntityExt.getBusinessType());
                try {
                    ProPermissionHelp.verifyQueryPermission(verifyViewPermissionDTO);
                } catch (XbbException e) {
                    continue;
                }
                //非ck环境，过滤掉供应商跟进记录
                if(!paasFormHelp.getCkFlag() && Objects.equals(XbbRefTypeEnum.SUPPLIER_COMMUNICATE.getCode(),paasFormEntityExt.getBusinessType())){
                    continue;
                }
                //数据集时，过滤与经销商有关的表单
                if(isDataSet && Objects.equals(DistributorMarkEnum.DISTRIBUTOR.getCode(),paasFormEntityExt.getDistributorMark())){
                    continue;
                }
                //数据集时，过滤新工单相关表单
                if (filterDataSetWorkOrder(isDataSet, paasFormEntityExt.getBusinessType())) {
                    continue;
                }
                //经销商管理应用如果关闭，过滤掉distributorMark 为1的表单
                if (!distributorFlag && Objects.equals(paasFormEntityExt.getDistributorMark(), 1)){
                    continue;
                }
                // 产品筛选暂时隐藏  预收/付款隐藏；客户对账单隐藏;经销商信用额度相关
                boolean hide =
//                        Objects.equals(paasFormEntityExt.getBusinessType(), XbbRefTypeEnum.PRODUCT.getCode()) ||
                        Objects.equals(paasFormEntityExt.getBusinessType(), XbbRefTypeEnum.PREPAYMENT_BALANCE.getCode())
                                || Objects.equals(paasFormEntityExt.getBusinessType(), XbbRefTypeEnum.PREPAY_BALANCE.getCode())
                                || Objects.equals(paasFormEntityExt.getBusinessType(), XbbRefTypeEnum.CUSTOMER_STATEMENT.getCode())
                                || Objects.equals(paasFormEntityExt.getBusinessType(), XbbRefTypeEnum.CUSTOMER_STATEMENT_STATISTIC.getCode())
                                || Objects.equals(paasFormEntityExt.getBusinessType(), XbbRefTypeEnum.ONLINE_PAYMENT_FLOW.getCode())
                                || Objects.equals(paasFormEntityExt.getBusinessType(), XbbRefTypeEnum.CREDIT_LIMIT.getCode())
                                || Objects.equals(paasFormEntityExt.getBusinessType(), XbbRefTypeEnum.CREDIT_TEMPORARY_LIMIT.getCode())
                                || Objects.equals(paasFormEntityExt.getBusinessType(), XbbRefTypeEnum.CREDIT_FIXED_LIMIT.getCode())
                                || Objects.equals(paasFormEntityExt.getBusinessType(), XbbRefTypeEnum.COST_ADJUST.getCode())
                        ;
                if(hide){
                    continue;
                }
                boolean supportBi = XbbTableRefEnum.supportBi(XbbRefTypeEnum.getByFlag(paasFormEntityExt.getSaasMark(), paasFormEntityExt.getBusinessType()));
                if(!supportBi){
                    continue;
                }
                // 单表工单未开启工单出库单不展示，多表直接不展示工单出库
                if (Objects.equals(paasFormEntityExt.getBusinessType(), XbbRefTypeEnum.WORK_ORDER_OUTSTOCK.getCode())) {
                    if (Objects.equals(0, single)) {
                        continue;
                    } else if (Objects.isNull(workOrderAppId)) {
                        continue;
                    }
                }
                //选了PASS表的要移除自己，SAAS的team里不会关联自己
                if(selfList.contains(paasFormEntityExt.getId())){
                    continue;
                }
                //跳过单表无意义的表单
                if(Objects.equals(1, single)){
                    if(BIProductReformEnum.getProductSubBusList().contains(paasFormEntityExt.getBusinessType())
                            || Objects.equals(paasFormEntityExt.getBusinessType(),XbbRefTypeEnum.CONTRACT_PERFORMANCE.getCode())){
                        continue;
                    }
                }else if (linkProduct) {
                    //如果已经选了产品子表单了，并且selectedFormList的size大于2，那么就需要把产品子表单关联的主业务的所有表单都移除掉(记住区分经销商),还有所有的产品子表单移除.
                    if (Objects.nonNull(removeProductMainFormBusiness)
                            && ((Objects.equals(removeProductMainFormBusiness, paasFormEntityExt.getBusinessType())
                            && Objects.equals(removePaasFormEntityExt.getDistributorMark(), paasFormEntityExt.getDistributorMark()))
                            || BIProductReformEnum.getProductSubBusList().contains(paasFormEntityExt.getBusinessType()))) {
                       continue;
                    } else if (BIProductReformEnum.getProductSubBusList().contains(paasFormEntityExt.getBusinessType())) {
                        allBiProductPaasFormIdList.add(paasFormEntityExt.getId());
                        allBiProductPaasFormList.add(paasFormEntityExt);
                        if (multipleProductCodeList.contains(paasFormEntityExt.getBusinessType())) {
                            multipleBiProductPaasFormIdList.add(paasFormEntityExt.getId());
                        }
                        continue;
                    }
                }
                //去除不在索引里的数据 - 关联子产品的除外
                if(SaasMarkEnum.SAAS.getCode().equals(paasFormEntityExt.getSaasMark()) && !multipleProductCodeList.contains(paasFormEntityExt.getBusinessType())){
                    if(!businessTypeList.contains(paasFormEntityExt.getBusinessType())){
                        //TODO  2019年5月20日16:39:42   暂时过滤掉不在ES中的数据
                        continue;
                    }
                }
                //去除没有使用权限的表单,noPermission为true  表示没有使用权限
                List<OptionalRangeEntity> optionalRangeList = JSONObject.parseArray(paasFormEntityExt.getPermission(), OptionalRangeEntity.class);
                Boolean noPermission = CollectionsUtil.isNotEmpty(optionalRangeList) && paasFormHelp.haveNoPermission(formAllListDTO.getLoginUser(), optionalRangeList);
                if (Objects.equals(paasFormEntityExt.getSaasMark(), SaasMarkEnum.SAAS.getCode()) && RedundantTemplateTypeEnum.isMultiTemplate(paasFormEntityExt.getBusinessType()) && noPermission) {
                    continue;
                }
                Long appId = paasFormEntityExt.getAppId();
                List<FormSimpleListVO>   formSimpleListVOList;
                if(menuMap.containsKey(appId)){
                    formSimpleListVOList = menuMap.get(appId);
                    if(formSimpleListVOList == null ){
                        formSimpleListVOList = new ArrayList<>();
                    }
                }else {
                    formSimpleListVOList = new ArrayList<>();
                }
                FormSimpleListVO  formSimpleListVO = new FormSimpleListVO();
                BeanUtil.copyProperties(paasFormEntityExt,formSimpleListVO);
                //
                formSimpleListVO.setFormId(paasFormEntityExt.getId());
                formSimpleListVOList.add(formSimpleListVO);
                menuMap.put(appId,formSimpleListVOList);
            }
            //有效的表单
            List<FormSimpleListVO>  newFormSimpleListVOList = new ArrayList<>();
            //根据产品子表单的formId去到form关系表中找父业务的formId,然后根据formId去查询出名称。如果父业务中有多个产品字段的，还要去表单解释里面拿
            if (linkProduct &&  selectedFormList.size() == BasicConstant.ZERO) {
                Map<String, Object> formRefMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                formRefMap.put("corpid", formAllListDTO.getCorpid());
                formRefMap.put("del", BasicConstant.ZERO);
                formRefMap.put("formIdList", allBiProductPaasFormIdList);
                List<PaasFormRefEntity> paasFormRefEntities = paasFormRefModel.findEntitys(formRefMap);
                if (CollectionsUtil.isNotEmpty(paasFormRefEntities)) {
                    Map<Long, PaasFormRefEntity> formAndMainFormIdMap = paasFormRefEntities.stream().collect(Collectors.toMap(PaasFormRefEntity::getFormId, Function.identity(), (key1,key2)->key2));
                    List<Long> mainFormIdList = paasFormRefEntities.stream().map(u -> u.getMainFormId()).collect(Collectors.toList());
                    Map<String, Object> mainFormMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    mainFormMap.put("corpid",formAllListDTO.getCorpid());
                    mainFormMap.put("idIn", mainFormIdList);
                    mainFormMap.put("del", BasicConstant.ZERO);
                    List<PaasFormEntityExt> mainFormList = paasFormModel.findEntitys(mainFormMap);
                    Map<Long, String> mainFormIdNameMap = mainFormList.stream().collect(Collectors.toMap(PaasFormEntityExt::getId, PaasFormEntityExt::getName, (key1,key2) ->key2));
                    //没有启用的主业务表单
                    List<Long> unEnAblePaasFormIdList = mainFormList.stream().filter(paasFormEntityExt -> Objects.equals(paasFormEntityExt.getEnable(), BasicConstant.ZERO)).map(PaasFormEntity::getId).collect(Collectors.toList());
                    List<Long> multipleBiProductMainPaasFormIdList = new ArrayList<>();
                    if (CollectionsUtil.isNotEmpty(multipleBiProductPaasFormIdList)) {
                        for (Long multipleBiProductPaasFormId : multipleBiProductPaasFormIdList) {
                            if (formAndMainFormIdMap.containsKey(multipleBiProductPaasFormId)) {
                                multipleBiProductMainPaasFormIdList.add(formAndMainFormIdMap.get(multipleBiProductPaasFormId).getMainFormId());
                            }
                        }
                    }
                    Map<String, Object> mainFormExplainParam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    mainFormExplainParam.put("corpid",formAllListDTO.getCorpid());
                    mainFormExplainParam.put("formIdIn", multipleBiProductMainPaasFormIdList);
                    mainFormExplainParam.put("enable", BasicConstant.ONE);
                    mainFormExplainParam.put("del", BasicConstant.ZERO);
                    List<PaasFormExplainEntity> mainPaasFormExplainList = paasFormExplainModel.findEntitys(mainFormExplainParam);
                    Map<Long, PaasFormExplainEntity> mainPaasFormExplainMap = mainPaasFormExplainList.stream().collect(Collectors.toMap(PaasFormExplainEntity::getFormId, Function.identity()));
                    for (PaasFormEntityExt paasFormEntityExt : allBiProductPaasFormList) {
                        Integer productBusinessType = paasFormEntityExt.getBusinessType();
                        Long subProductFormId = paasFormEntityExt.getId();
                        PaasFormRefEntity paasFormRefEntity = formAndMainFormIdMap.get(subProductFormId);
                        if (Objects.isNull(paasFormRefEntity)) {
                            continue;
                        }
                        Long mainFormId = paasFormRefEntity.getMainFormId();
                        Integer type = paasFormRefEntity.getType();
                        if (unEnAblePaasFormIdList.contains(mainFormId)) {
                            continue;
                        }
                        String mainFormName = mainFormIdNameMap.get(mainFormId);
                        String linkProductAttr = BIProductReformEnum.getProductAttr(productBusinessType, type);
                        //下面分两种情况，如果一个主业务对应多个产品的话，产品子表单名称就要具体到具体产品名称；如果一个主业务对应
                        if (!multipleProductCodeList.contains(productBusinessType)) {
                            paasFormEntityExt.setName(String.format(I18nMessageUtil.getMessage(RelatedProductConstant.PRODUCT_LINK_NAME), mainFormName));
                        }else {
                            //一个主业务对应多个产品的情况，这时候就需要拿到表单解释里面的具体的产品名称
                            PaasFormExplainEntity paasFormExplainEntity = mainPaasFormExplainMap.get(mainFormId);
                            List<FieldAttrEntity> explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
                            Map<String, FieldAttrEntity> explainMap = explainList.stream().collect(Collectors.toMap(FieldAttrEntity::getAttr, Function.identity()));
                            FieldAttrEntity fieldAttrEntity = explainMap.get(linkProductAttr);
                            paasFormEntityExt.setName(String.format(I18nMessageUtil.getMessage(RelatedProductConstant.PRODUCT_LINK_NAME_SEN), mainFormName, fieldAttrEntity.getAttrName()));
                        }
                        FormSimpleListVO  formSimpleListVO = new FormSimpleListVO();
                        BeanUtil.copyProperties(paasFormEntityExt,formSimpleListVO);
                        formSimpleListVO.setFormId(paasFormEntityExt.getId());
                        newFormSimpleListVOList.add(formSimpleListVO);
                    }
                }
            }
            List<FormResultListVO> resultList = new ArrayList<>();
            //把应用和表单对应
            for (PaasAppEntity paasAppEntity : appList) {
                FormResultListVO formResultListVO = new FormResultListVO();
                Long appId = paasAppEntity.getId();
                List<FormSimpleListVO>  formSimpleListVOList = menuMap.get(appId);
                //这边要兼容一种情况，就是selectedFormList为1，并且表单未启用，这时候应用还是要返回，只是表单不返回
                if (CollectionsUtil.isNotEmpty(selectedFormList) && selectedFormList.size() == BasicConstant.ONE
                        && appNameShowTag && Objects.nonNull(appNameShowTagFormEntityExt) && Objects.equals(appNameShowTagFormEntityExt.getAppId(), appId)) {
                    resultList = new ArrayList<>();
                    formResultListVO.setAppId(appId);
                    formResultListVO.setAppName(paasAppEntity.getName());
                    formResultListVO.setFormList(new ArrayList<>());
                    resultList.add(formResultListVO);
                    break;
                } else {
                    if (formSimpleListVOList == null || formSimpleListVOList.isEmpty()){
                        continue;
                    }
                    if (Objects.equals(paasAppEntity.getAlias(), XbbRefTypeEnum.MARKETING_MANAGEMENT.getAlias())){
                        continue;
                    }
                    //因为多表需要把产品子表单放到产品应用下
                    if (linkProduct && Objects.equals(paasAppEntity.getAlias(), ProductMenuEnum.PRODUCT.getAlias())) {
                        newFormSimpleListVOList.forEach(formSimpleListVO -> formSimpleListVO.setAppId(appId));
                        formSimpleListVOList.addAll(newFormSimpleListVOList);
                    }
                    formResultListVO.setFormList(formSimpleListVOList);
                    formResultListVO.setAppId(appId);
                    formResultListVO.setAppName(paasAppEntity.getName());
                    resultList.add(formResultListVO);
                }
            }
            formAllListVO.setAppList(resultList);
        } catch (XbbException e) {
            LOG.error("paasFormService数据库查询表单出错", e);
            throw e;
        } catch (Exception e) {
            LOG.error("paasFormService数据库查询表单出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formAllListVO;
    }
    /**
     * @author  gzt
     * @Description 数据集过滤掉新工单相关表单
     * @Date 13:43 2023/4/18
     * @param isDataSet  是否是数据集
     * @param businessType
     * @return boolean
     * @throws
     **/

    private boolean filterDataSetWorkOrder(boolean isDataSet, Integer businessType) {
        if(isDataSet && (Objects.equals(XbbRefTypeEnum.WORK_ORDER_V2.getCode(), businessType)
        ||Objects.equals(XbbRefTypeEnum.WORK_ORDER_V2_PRODUCT.getCode(), businessType)
        ||Objects.equals(XbbRefTypeEnum.WORK_ORDER_V2_POOL.getCode(), businessType)
        ||Objects.equals(XbbRefTypeEnum.WORK_ORDER_V2_APPOINT.getCode(), businessType)
        ||Objects.equals(XbbRefTypeEnum.ALL_WORK_ORDER_V2.getCode(), businessType)
        ||Objects.equals(XbbRefTypeEnum.SLA_LOG.getCode(), businessType)
        ||Objects.equals(XbbRefTypeEnum.RECEIPT_ORDER.getCode(), businessType)
        ||Objects.equals(XbbRefTypeEnum.SERVICE_PROJECT.getCode(), businessType)
        ||Objects.equals(XbbRefTypeEnum.WORK_ORDER_V2_NODE_INFO.getCode(), businessType))){
            return true;
        }
        return false;
    }


    @Override
    public ComboLinkExplainListVO comboLinkExplainList(ComboLinkExplainListDTO comboLinkExplainListDTO) throws XbbException {
        ComboLinkExplainListVO comboLinkExplainListVO = new ComboLinkExplainListVO();
        try {
            String corpid = comboLinkExplainListDTO.getCorpid();
            Map<String, Object> param = BeanUtil.convertBean2Map(comboLinkExplainListDTO, true);
            List<PaasAppEntity> appList = paasAppModel.list(param);
            if(appList == null || appList.isEmpty()) {
                comboLinkExplainListVO.setAppList(new ArrayList<>());
                return comboLinkExplainListVO;
            }
            Long workOrderAppId = null;
            for (PaasAppEntity paasAppEntity : appList) {
                if (Objects.equals(paasAppEntity.getAlias(), XbbRefTypeEnum.WORK_ORDER.getAlias())) {
                    workOrderAppId = paasAppEntity.getId();
                }
            }
            Map<String, Object> map = BeanUtil.convertBean2Map(comboLinkExplainListDTO, true);
            List<PaasFormExplainEntity> explainList = paasFormExplainModel.findEntitys(map);
            if(explainList == null || explainList.isEmpty()) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
            map.clear();
            map = BeanUtil.convertBean2Map(comboLinkExplainListDTO, true);
            // 菜单id为0为bi表单，无需搜出
            map.put("negMenuId", 0);
            List<PaasFormEntityExt> list = paasFormModel.list(map);
            if(list == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
            }
            // 工单表单列表
            List<PaasFormEntityExt> workOrderFormList = getWorkOrderList(corpid, workOrderAppId);
            list.addAll(workOrderFormList);
            Map<Long, List<PaasFormVo>> formMap = new HashMap<>(list.size());
            // 获取工单表单字段解释
            explainList.addAll(getWorkOrderExplainList(corpid, workOrderFormList));
            Map<Long, List<ReturnExplainPojo>> explainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (PaasFormExplainEntity explain: explainList) {
                // 将字段进行集合，可以迅速返回字段列表
                explainMap.put(explain.getFormId(), getComboLinkField(explain));
            }
            List<Integer> blockList = Arrays.asList(XbbRefTypeEnum.CUSTOMER_STATEMENT.getCode(), XbbRefTypeEnum.CUSTOMER_STATEMENT_STATISTIC.getCode());
            if(comboLinkExplainListDTO.getMenuId() != null){
                for (PaasFormEntityExt paasFormEntityExt : list) {
                    // 过滤当前表单的数据
                    if(paasFormEntityExt.getId().equals(comboLinkExplainListDTO.getFormId())){
                        continue;
                    }
                    // 过滤掉bi的一些表单
                    BIProductEnum biProductEnum = BIProductEnum.getByCode(paasFormEntityExt.getBusinessType());
                    if (Objects.nonNull(biProductEnum) ||
                            Objects.equals(paasFormEntityExt.getBusinessType(), XbbRefTypeEnum.CONTRACT_PERFORMANCE.getCode())) {
                        continue;
                    }
                    // 过滤掉周报，日报，月报
                    WorkReportEnum workReportEnum = WorkReportEnum.getByCode(paasFormEntityExt.getBusinessType());
                    if (Objects.nonNull(workReportEnum)) {
                        continue;
                    }
                    // 过滤掉一些特殊的业务表单
                    if (blockList.contains(paasFormEntityExt.getBusinessType())) {
                        continue;
                    }
                    PaasFormVo menuVo = new PaasFormVo();
                    BeanUtil.copyProperties(paasFormEntityExt, menuVo);
                    if (formMap.containsKey(paasFormEntityExt.getAppId())) {
                        List<PaasFormVo> formList = formMap.get(paasFormEntityExt.getAppId());
                        menuVo.setChildren(explainMap.get(paasFormEntityExt.getId()));
                        formList.add(menuVo);
                        formMap.put(paasFormEntityExt.getAppId(), formList);
                    } else {
                        List<PaasFormVo> formList = new ArrayList<>();
                        menuVo.setChildren(explainMap.get(paasFormEntityExt.getId()));
                        formList.add(menuVo);
                        formMap.put(paasFormEntityExt.getAppId(), formList);
                    }
                }
            }
            List<AppListReturnPojo> appListReturn = new ArrayList<>();
            appList.forEach(item->{
                AppListReturnPojo appListReturnPojo = new AppListReturnPojo();
                BeanUtil.copyProperties(item, appListReturnPojo);
                appListReturnPojo.setChildren(formMap.get(item.getId()));
                appListReturn.add(appListReturnPojo);
            });
            comboLinkExplainListVO.setAppList(appListReturn);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasFormService数据库查询表单及其字段出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return comboLinkExplainListVO;
    }

    /**
     * 获取下拉框关联其他表单的字段
     * @param entity 表单的字段数据列表
     * @return 返回符合条件的字段
     * @throws XbbException
     */
    public List<ReturnExplainPojo> getComboLinkField(PaasFormExplainEntity entity) throws XbbException{
        List<ReturnExplainPojo> resultFieldList = new ArrayList<>();
        try {
            List<FieldAttrEntity> fieldList = JSONArray.parseArray(entity.getExplains(), FieldAttrEntity.class);
            for (FieldAttrEntity fieldEntity: fieldList) {
                Integer fieldType = fieldEntity.getFieldType();
                Integer showType = fieldEntity.getShowType();
                // 过滤不可见字段
                if (Objects.nonNull(showType) && (ShowTypeEnum.LIST.getCode() == showType || ShowTypeEnum.DETAIL.getCode() == showType
                        || ShowTypeEnum.LIST_DETAIL.getCode() == showType || ShowTypeEnum.NONE.getCode() == showType)) {
                    continue;
                }
                if (!Objects.equals(1, fieldEntity.getIsOpen())) {
                    // 过滤掉未启用和回收站的字段
                    continue;
                }
                if(ComboLinkFieldEnum.getComboLinkFieldEnum(fieldType) != null){
                    ReturnExplainPojo returnExplainPojo = new ReturnExplainPojo(fieldEntity.getAttr(), fieldEntity.getAttrName(), fieldEntity.getAttrName(), fieldType, fieldEntity.getSubForm());
                    resultFieldList.add(returnExplainPojo);
                }
            }
        } catch (Exception e) {
            LOG.error("获取下拉框关联其他表单的字段时报错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return resultFieldList;
    }
    @Override
    public UserApproveListVO userApproveList(UserApproveListDTO userApproveListDTO) throws XbbException {
        UserApproveListVO userApproveListVO = new UserApproveListVO();
        try {
            Map<String, Object> map = BeanUtil.convertBean2Map(userApproveListDTO);
            List<PaasFormEntityExt> list = paasFormModel.userFormList(map);
            if(list == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.USER_APPROVE_FORM_NOT_EXIST);
            }
            userApproveListVO.setFormList(list);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasFormService数据库用户的审批表单出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return userApproveListVO;
    }

    @Override
    public FormTitleListVO titleList(FormTitleListDTO formTitleListDTO) throws XbbException {
        FormTitleListVO formTitleListVO = new FormTitleListVO();
        try {
            Map<String, Object> param = BeanUtil.convertBean2Map(formTitleListDTO);
            List<PaasFormExplainEntity> explainList = paasFormExplainModel.list(param);
            if (explainList == null || explainList.isEmpty()) {
                return formTitleListVO;
            }
            JSONArray explainJsonArray = JSONArray.parseArray(explainList.get(0).getExplains());
            List<PaasFormEntityExt> list = paasFormModel.list(param);
            if (list == null || list.isEmpty()) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
            }
            PaasFormEntityExt entityExt = list.get(0);
            List<FormTitlePoJo> formTitlePoJoList = new ArrayList<>();
            List<FormTitlePoJo> customTitleList = JSONArray.parseArray(entityExt.getCustomTitle(), FormTitlePoJo.class);
            if(customTitleList != null) {
                for (Object object: explainJsonArray) {
                    JSONObject jsonObject = (JSONObject) object;
                    String attr = jsonObject.getString("attr");
                    String attrName = jsonObject.getString("attrName");
                    Integer fieldType = jsonObject.getInteger("fieldType");
                    for (FormTitlePoJo formTitle: customTitleList) {
                        FormTitlePoJo formTitlePoJo = new FormTitlePoJo();
                        // 获取需要过滤的标题字段
                        if(formTitle.getAttr().equals(attr) && !TitleSupportFieldEnum.isHasNeedFilterField(fieldType)){
                            formTitlePoJo.setAttrName(attrName);
                            formTitlePoJo.setAttr(attr);
                            formTitlePoJoList.add(formTitlePoJo);
                        }
                        if(StringUtil.isNotEmpty(formTitle.getContent())){
                            formTitlePoJo.setContent(formTitle.getContent());
                            formTitlePoJoList.add(formTitlePoJo);
                        }
                    }
                }
            }
            formTitleListVO.setFormTitleList(formTitlePoJoList);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("paasFormService数据库设置表单标题出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formTitleListVO;
    }

    @Override
    public FormRoleDetailVO roleDetail(FormRoleDetailDTO roleDetailDTO) throws XbbException {
        FormRoleDetailVO roleDetailVO = new FormRoleDetailVO();
        String corpid = roleDetailDTO.getCorpid();
        Integer roleId = roleDetailDTO.getRoleId();
        Long menuId = roleDetailDTO.getMenuId();
        Long appId = roleDetailDTO.getAppId();
        Integer saasMark = roleDetailDTO.getSaasMark();
        Integer businessType4Distributor = XbbRefTypeEnum.transferBusinessType4Distributor(roleDetailDTO.getBusinessType(), roleDetailDTO.getDistributorMark());
        roleDetailDTO.setBusinessType(businessType4Distributor);

        try {
            RoleEntity role = roleModel.getByKey(roleId, corpid);
            if (role == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.ROLE_NOT_EXIST);
            }

            FormRoleDetailVO formRoleDetailVO;
            if (saasMark.equals(SaasMarkEnum.SAAS.getCode())) {
                // 格式化saas表单模块权限，从数据库存储格式 ==> List<PermissionComplexTermPojo>
                formRoleDetailVO = formatSaasModulePermission(corpid, businessType4Distributor, role);
            } else {
                // 格式化paas应用模块权限，从数据库存储格式 ==> List<PermissionComplexTermPojo>
                formRoleDetailVO = formatPaasModulePermission(corpid, appId, menuId, role);
            }

            List<PermissionComplexTermPojo> permissions = formRoleDetailVO.getPermission();

            Iterator<PermissionComplexTermPojo> iterator = permissions.iterator();

            while (iterator.hasNext()) {
                PermissionComplexTermPojo permission = iterator.next();
                if (permission.getAlias().indexOf("Esign") > 0 || Objects.equals(permission.getAlias(), SaasButtonEnum.ESIGN.getAttr())) {
                    HasEsignDTO hasEsignDTO = new HasEsignDTO();
                    hasEsignDTO.setFormId(roleDetailDTO.getFormId());
                    hasEsignDTO.setCorpid(corpid);
                    HasEsignVO hasEsignVO = esignService.hasEsign(hasEsignDTO);

                    if (Objects.equals(hasEsignVO.getEnable(), BasicConstant.ZERO)) {
                        iterator.remove();
                    }
                }
            }


            BeanUtil.copyProperties(roleDetailDTO, roleDetailVO);
            roleDetailVO.setPermission(permissions);
            roleDetailVO.setDataPermission(formRoleDetailVO.getDataPermission());
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("PaasFormServiceImpl.roleDetail执行出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }

        return roleDetailVO;
    }

    @Override
    public FormRoleUpdateVO roleUpdate(FormRoleUpdateDTO roleUpdateDTO) throws XbbException {
        FormRoleUpdateVO roleUpdateVO = new FormRoleUpdateVO();
        String corpid = roleUpdateDTO.getCorpid();
        Integer roleId = roleUpdateDTO.getRoleId();
        Long menuId = roleUpdateDTO.getMenuId();
        Long appId = roleUpdateDTO.getAppId();
        Integer saasMark = roleUpdateDTO.getSaasMark();
        Integer businessType = roleUpdateDTO.getBusinessType();

        List<PermissionComplexTermPojo> permission = roleUpdateDTO.getPermission();
        if (permission == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PERMS_PARAMS_CAN_NOT_BE_EMPTY);
        }

        RoleEntity role = roleModel.getByKey(roleId, corpid);
        if (role == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.ROLE_NOT_EXIST);
        }

        Integer dataPermission = roleUpdateDTO.getDataPermission();
        if (dataPermission == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, String.format(MessageConstant.CAN_NOT_BE_EMPTY, "数据权限参数"));
        }

        try {
            // 系统角色修改逻辑，原逻辑是抛出异常
            CoverRoleEntity coverRole = null;
            if (role.getCorpid().equals(PaasConstant.DEFAULT_DATA_CORPID)) {
                /*
                 * 不能修改管理员角色和老板系统角色
                 */
                if (role.isAdminOrBoss()) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100092);
                }

                // 将cover_role表中的数据覆盖到role中
                coverRole = coverRoleModel.getByRoleId(role.getId(), corpid);
                if (coverRole == null) {
                    coverRole = new CoverRoleEntity();
                    coverRole.setCorpid(corpid);
                    coverRole.setRoleId(roleId);
                    coverRole.setRoleName(role.getRoleName());
                }
            }

            // saas应用权限和paas应用权限保存逻辑区分
            if (saasMark.equals(SaasMarkEnum.SAAS.getCode())) {
                // saas菜单/表单权限保存逻辑
                saasPermissionSave(businessType, role, permission, dataPermission);
                dynamicSaasPermissionSave(corpid, appId, businessType, role, permission);
            } else {
                // paas应用权限保存逻辑
                paasPermissionSave(appId, menuId, role, permission, dataPermission, corpid);
                dynamicPaasPermissionSave(appId, menuId, role, permission, corpid);
            }

            if (role.getCorpid().equals(PaasConstant.DEFAULT_DATA_CORPID)) {
                coverRole.setPermissions(role.getPermissions());
                String rolePassPermission = role.getPaasPermissions() == null ? "" : role.getPaasPermissions();
                coverRole.setPaasPermissions(rolePassPermission);
                coverRole.setDataPermissionDetail(role.getDataPermissionDetail());
                coverRoleModel.save(coverRole);
            } else {
                roleModel.update(role);
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("PaasFormServiceImpl.roleDetail执行出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }

        BeanUtil.copyProperties(roleUpdateDTO, roleUpdateDTO);

        String userId = roleUpdateDTO.getUserId();
        String userName = roleUpdateDTO.getLoginUserName();
        // 记录日志
        String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_UPDATE_ROLE), userName, role.getRoleName());
        mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.ROLE, OperateTypeEnum.EDIT,
                role.getId().toString(), role.getRoleName(), memo, roleUpdateDTO.getHttpHeader());

        return roleUpdateVO;
    }

    /**
     * 动态权限设置入role中
     * 1、移除原来的businessType下的权限
     * 2、设置当前设置的权限
     * @param appId
     * @param businessType
     * @param role
     * @param permission
     * @throws XbbException
     */
    private void dynamicSaasPermissionSave(String corpid, Long appId, Integer businessType, RoleEntity role, List<PermissionComplexTermPojo> permission) throws XbbException {
        if (businessType == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002, MessageConstant.ABNORMAL_PARAMETER, "businessType");
        }
        // 原数据库权限
        List<DynamicPermissionPojo> dynamicPermissions = JSON.parseArray(role.getDynamicPermissions(), DynamicPermissionPojo.class);
        // 为空时候的初始化
        if (dynamicPermissions == null) {
            dynamicPermissions = new ArrayList<>();
        }
        //找到appId对应的相关权限
        DynamicPermissionPojo dynamicPermissionPojo = null;
        for (DynamicPermissionPojo dynamicPermission : dynamicPermissions) {
            if (Objects.equals(dynamicPermission.getAppId(), appId)) {
                dynamicPermissionPojo = dynamicPermission;
            }
        }

        if (Objects.nonNull(dynamicPermissionPojo)) {
            removePermissionByBusinessType(corpid, dynamicPermissionPojo, businessType);
        }

        //获取当前设置的权限
        List<DynamicPermissionSubPojo> modules = new ArrayList<>();
        for (PermissionComplexTermPojo pojo : permission) {
            if (cloudCodeHelp.isCloudCodeAlias(pojo.getAlias()) && Objects.equals(pojo.getValue(), BasicConstant.ONE)) {
                DynamicPermissionSubPojo dynamicPermissionSubPojo = new DynamicPermissionSubPojo();
                dynamicPermissionSubPojo.setBusinessType(businessType);
                dynamicPermissionSubPojo.setAlias(pojo.getAlias());
                dynamicPermissionSubPojo.setName(pojo.getName());
                modules.add(dynamicPermissionSubPojo);
            }
        }

        if (!modules.isEmpty()) {
            if (Objects.isNull(dynamicPermissionPojo)) {
                dynamicPermissionPojo = new DynamicPermissionPojo();
                dynamicPermissions.add(dynamicPermissionPojo);
            }
            List<DynamicPermissionSubPojo> orModules = dynamicPermissionPojo.getModules();
            if (Objects.isNull(orModules)) {
                orModules = new ArrayList<>();
            }
            orModules.addAll(modules);
            dynamicPermissionPojo.setAppId(appId);
            dynamicPermissionPojo.setModules(orModules);
        }

        //应用下没有权限移除
        dynamicPermissions.removeIf(dynamicPermission->(dynamicPermission.getModules().isEmpty()));

        role.setDynamicPermissions(JSON.toJSONString(dynamicPermissions));
    }

    /**
     * 通过businessType移除dynamicPermissionPojo中的相关权限
     * @param corpid
     * @param dynamicPermissionPojo
     * @param businessType
     * 创建时间 2020/9/28 2:45 PM
     * 修改时间 2020/9/28 2:45 PM
     * @author chy
     */
    private void removePermissionByBusinessType(String corpid, DynamicPermissionPojo dynamicPermissionPojo, Integer businessType) {

        if (Objects.isNull(dynamicPermissionPojo.getModules())) {
            dynamicPermissionPojo.setModules(new ArrayList<>());
        }

        if (dynamicPermissionPojo.getModules().isEmpty()) {
            return;
        }
        Set<String> aliasSet = cloudCodeHelp.getAliasSetByBusinessType(corpid, businessType);
        List<DynamicPermissionSubPojo> modules = dynamicPermissionPojo.getModules();
        modules.removeIf(dynamicPermissionSub->aliasSet.contains(dynamicPermissionSub.getAlias()));
    }

    /**
     * paas表单下的动态权限保存
     * 1、paas业务表单，menuId唯一对应一个form，通过menuId获取到对应的formId
     * 2、找到appId下的权限，
     * 3、移除formId下的动态权限
     * 4、加上现在选中的动态权限
     * 5、移除权限中空权限的项
     *
     * @param appId
     * @param menuId
     * @param role
     * @param permissions
     * @param corpid
     * @throws XbbException
     * 创建时间 2020/9/28 4:25 PM
     * 修改时间 2020/9/28 4:25 PM
     * @author chy
     */
    private void dynamicPaasPermissionSave(Long appId, Long menuId, RoleEntity role, List<PermissionComplexTermPojo> permissions, String corpid) throws XbbException {
        if (menuId == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002, MessageConstant.ABNORMAL_PARAMETER, "menuId");
        }

        PaasFormEntityExt paasForm = paasFormModel.getByMenuId(menuId, corpid);
        if (Objects.isNull(paasForm)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100018);
        }

        // 原数据库权限
        List<DynamicPermissionPojo> dynamicPermissions = JSON.parseArray(role.getDynamicPermissions(), DynamicPermissionPojo.class);
        // 为空时候的初始化
        if (dynamicPermissions == null) {
            dynamicPermissions = new ArrayList<>();
        }
        //找到appId对应的相关权限
        DynamicPermissionPojo dynamicPermissionPojo = null;
        for (DynamicPermissionPojo dynamicPermission : dynamicPermissions) {
            if (Objects.equals(dynamicPermission.getAppId(), appId)) {
                dynamicPermissionPojo = dynamicPermission;
            }
        }

        if (Objects.nonNull(dynamicPermissionPojo)) {
            removePermissionByFormId(corpid, dynamicPermissionPojo, paasForm.getId());
        }

        //获取当前设置的权限
        List<DynamicPermissionSubPojo> modules = new ArrayList<>();
        for (PermissionComplexTermPojo pojo : permissions) {
            if (cloudCodeHelp.isCloudCodeAlias(pojo.getAlias()) && Objects.equals(pojo.getValue(), BasicConstant.ONE)) {
                DynamicPermissionSubPojo dynamicPermissionSubPojo = new DynamicPermissionSubPojo();
                dynamicPermissionSubPojo.setFormId(paasForm.getId());
                dynamicPermissionSubPojo.setAlias(pojo.getAlias());
                dynamicPermissionSubPojo.setName(pojo.getName());
                modules.add(dynamicPermissionSubPojo);
            }
        }

        if (!modules.isEmpty()) {
            if (Objects.isNull(dynamicPermissionPojo)) {
                dynamicPermissionPojo = new DynamicPermissionPojo();
                dynamicPermissions.add(dynamicPermissionPojo);
            }
            List<DynamicPermissionSubPojo> orModules = dynamicPermissionPojo.getModules();
            if (Objects.isNull(orModules)) {
                orModules = new ArrayList<>();
            }
            orModules.addAll(modules);
            dynamicPermissionPojo.setAppId(appId);
            dynamicPermissionPojo.setModules(orModules);
        }

        //应用下没有权限移除
        dynamicPermissions.removeIf(dynamicPermission->(dynamicPermission.getModules().isEmpty()));

        role.setDynamicPermissions(JSON.toJSONString(dynamicPermissions));
    }

    /**
     * 移除formId下的权限项
     * @param corpid
     * @param dynamicPermissionPojo
     * @param formId
     * 创建时间 2020/9/28 4:31 PM
     * 修改时间 2020/9/28 4:31 PM
     * @author chy
     */
    private void removePermissionByFormId(String corpid, DynamicPermissionPojo dynamicPermissionPojo, Long formId) {

        if (Objects.isNull(dynamicPermissionPojo.getModules())) {
            dynamicPermissionPojo.setModules(new ArrayList<>());
        }

        if (dynamicPermissionPojo.getModules().isEmpty()) {
            return;
        }
        Set<String> aliasSet = cloudCodeHelp.getAliasSetByFormId(corpid, formId);
        List<DynamicPermissionSubPojo> modules = dynamicPermissionPojo.getModules();
        modules.removeIf(dynamicPermissionSub->aliasSet.contains(dynamicPermissionSub.getAlias()));
    }

    @Override
    public Map<Long, String> getNameMap(String corpid, int businessType) {
        Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("corpid",corpid);
        map.put("businessType",businessType);
        map.put("del",0);
        map.put("saasMark",SaasMarkEnum.SAAS.getCode());
        List<PaasFormEntityExt> paasFormEntityExtList = paasFormModel.list(map);
        Map<Long,String> nameMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (PaasFormEntityExt entityExt : paasFormEntityExtList){
            nameMap.put(entityExt.getId(),entityExt.getName());
        }
        return nameMap;
    }

    @Override
    public QuickNewListVO quickNewList(QuickNewListDTO quickNewListDTO) throws XbbException {
        QuickNewListVO quickNewListVO = new QuickNewListVO();
        try {
            MenuNewListDTO menuNewListDTO = new MenuNewListDTO();
            BeanUtil.copyProperties(quickNewListDTO, menuNewListDTO);
            MenuNewListVO menuNewListVO = new MenuNewListVO();
            List<MenuReturnPojo> quickNewList = paasMenuService.getQuickNewFormList(menuNewListDTO, menuNewListVO, true, true);
            Set<Long> menuIdIn = new HashSet<>();
            quickNewList.forEach(item->{
                menuIdIn.add(item.getMenuId());
            });
            List<QuickNewGetVO> quickList = new ArrayList<>();
            Boolean enableWorkReport = false;
            if (!menuIdIn.isEmpty()) {
                Map<String, Object> param = BeanUtil.convertBean2Map(quickNewListDTO, true);
                param.put("idIn", menuIdIn);
                param.put("orderByStr", " sort ASC, update_time ASC ");
                param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                param.put("enable", 1);
                // 经销商关闭后经销商相关表单隐藏
                Boolean distributorEnable = paasAppService.validateAppEnable(null, XbbRefTypeEnum.DISTRIBUTOR.getAlias(), SaasMarkEnum.SAAS.getCode(), menuNewListDTO.getCorpid());
                if (!distributorEnable) {
                    param.put("distributorMark", DistributorMarkEnum.OTHER.getCode());
                }
                List<PaasMenuEntity> paasMenuList = paasMenuModel.findEntitys(param);
                if (Objects.isNull(paasMenuList)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.MENU_NOT_EXIST);
                }
                Set<String> parentAliasIn = new HashSet<>();
                paasMenuList.forEach(item->{
                    parentAliasIn.add(item.getAlias());
                    if (Objects.equals(item.getAlias(), XbbRefTypeEnum.CUSTOMER.getAlias()) || Objects.equals(item.getAlias(), XbbRefTypeEnum.CUSTOMER_FOCUS.getAlias())
                    || Objects.equals(item.getAlias(), XbbRefTypeEnum.CUSTOMER_DEAL.getAlias()) || Objects.equals(item.getAlias(), XbbRefTypeEnum.CUSTOMER_FOLLOW.getAlias())
                    || Objects.equals(item.getAlias(), XbbRefTypeEnum.CUSTOMER_PUBLIC.getAlias()) || Objects.equals(item.getAlias(), XbbRefTypeEnum.CUSTOMER_RECYCLE.getAlias())
                            || Objects.equals(item.getAlias(), XbbRefTypeEnum.CUSTOMER_NEARBY.getAlias())) {
                        parentAliasIn.add(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getAlias());
                    }else if (Objects.equals(item.getAlias(), XbbRefTypeEnum.ALL_OPPORTUNITY.getAlias()) || Objects.equals(item.getAlias(), XbbRefTypeEnum.KEY_OPPORTUNITY.getAlias())) {
                        parentAliasIn.add(XbbRefTypeEnum.SALES_OPPORTUNITY.getAlias());
                    } else if (Objects.equals(item.getAlias(), XbbRefTypeEnum.ALL_CLUE.getAlias()) || Objects.equals(item.getAlias(), XbbRefTypeEnum.CLUE_PUBLIC.getAlias())
                            || Objects.equals(item.getAlias(), XbbRefTypeEnum.CLUE_RECYCLE.getAlias())) {
                        parentAliasIn.add(XbbRefTypeEnum.CLUE.getAlias());
                    }

                });
                String corpid = quickNewListDTO.getCorpid();
                if (!parentAliasIn.isEmpty()) {
                    param.clear();
                    param.put(StringConstant.CORPID, corpid);
                    param.put("aliasIn", parentAliasIn);
                    param.put("orderByStr", " sort ASC, update_time ASC ");
                    param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                    if (!distributorEnable) {
                        param.put("distributorMark", DistributorMarkEnum.OTHER.getCode());
                    }
                    List<PaasMenuEntity> parentMenuList = paasMenuModel.findEntitys(param);
                    if (Objects.isNull(parentMenuList)) {
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.MENU_NOT_EXIST);
                    }
                    paasMenuList.addAll(parentMenuList);
                }
                // 判断菜单权限
                List<Long> menuIdList = new ArrayList<>();
                List<Long> workOrderMenuIdList = new ArrayList<>();
                List<PaasMenuEntity> menuList = new ArrayList<>();
                List<PaasMenuEntity> workOrderMenuList = new ArrayList<>();
                UserVO userVO = quickNewListDTO.getLoginUser();
                Boolean hasWorkOrder = false;
                //根据套餐获取当前公司套餐不能看到的菜单
                List<String> unSeeMenuList = packageHelp.getUnSeeMenuList(corpid);
                for (PaasMenuEntity paasMenuEntity : paasMenuList) {
                    Boolean hasPermission = proMenuHelp.validateAddPermission(userVO, paasMenuEntity);
                    if (!userVO.isAdminOrBoss() && !hasPermission) {
                        continue;
                    }
                    String alias = paasMenuEntity.getAlias();
                    if (Objects.equals(paasMenuEntity.getSaasMark(), SaasMarkEnum.SAAS.getCode()) && unSeeMenuList.contains(alias)) {
                        continue;
                    }
                    if (Objects.equals(XbbRefTypeEnum.WORK_REPORT.getAlias(), alias)) {
                        enableWorkReport = true;
                    }
                    if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getAlias(), alias)) {
                        hasWorkOrder = true;
                        workOrderMenuList.add(paasMenuEntity);
                        workOrderMenuIdList.add(paasMenuEntity.getId());
                    } else {
                        menuIdList.add(paasMenuEntity.getId());
                        menuList.add(paasMenuEntity);
                    }

                }
                if (menuIdList.isEmpty() && workOrderMenuIdList.isEmpty()) {
                    quickNewListVO.setWorkReportQuickNewList(new ArrayList<>());
                    quickNewListVO.setQuickList(new ArrayList<>());
                    return quickNewListVO;
                }
                param.clear();
                param.put("menuIdIn", menuIdList);
                param.put("corpid", corpid);
                param.put("enable", 1);
                //param.put("orderByStr", "update_time ASC ");
                param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                List<PaasFormEntityExt> paasFormList = paasFormModel.list(param);
                if (Objects.isNull(paasFormList)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
                }
                List<WorkOrderFormEntity> workOrderFormList = new ArrayList<>();
                if (hasWorkOrder) {
                    PaasAppEntity appEntity = paasAppModel.getByAlias(XbbRefTypeEnum.WORK_ORDER.getAlias(), corpid);
                    if (Objects.nonNull(appEntity)) {
                        TransmittableThreadLocalUtil.setValue(SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.WORK_ORDER.getCode(), null, DistributorMarkEnum.OTHER.getCode());
                        workOrderFormList = workOrderFormService.getTemplateWithPermission(quickNewListDTO.getLoginUser(), appEntity.getId(), null);
                    }
                }
                Map<Long, PaasFormEntityExt> workOrderFormMap = new HashMap<>(paasFormList.size());
                workOrderFormList.forEach(item->{
                    PaasFormEntityExt paasFormEntityExt = new PaasFormEntityExt();
                    BeanUtil.copyProperties(item, paasFormEntityExt);
                    if (!workOrderFormMap.containsKey(item.getMenuId())) {
                        workOrderFormMap.put(item.getMenuId(), paasFormEntityExt);
                    }
                });
                Map<Long, PaasFormEntityExt> formMap = new HashMap<>(paasFormList.size());
                Map<String, PaasFormEntityExt> otherFormMap = new HashMap<>(paasFormList.size());
                for (PaasFormEntityExt paasFormEntityExt : paasFormList) {
                    //去除没有权限的多模板类型（客户 合同 销售）
                    Boolean isMultiTemplate =  RedundantTemplateTypeEnum.isMultiTemplate(paasFormEntityExt.getBusinessType());
                    List<OptionalRangeEntity> optionalRangeList = JSONObject.parseArray(paasFormEntityExt.getPermission(), OptionalRangeEntity.class);
                    Boolean noPermission = optionalRangeList != null && !optionalRangeList.isEmpty() && paasFormHelp.haveNoPermission(quickNewListDTO.getLoginUser(), optionalRangeList);
                    // 判断合同和客户多模板的权限
                    if (Objects.equals(paasFormEntityExt.getSaasMark(), SaasMarkEnum.SAAS.getCode()) && isMultiTemplate && noPermission) {
                        continue;
                    }
                    if (!formMap.containsKey(paasFormEntityExt.getMenuId())) {
                        formMap.put(paasFormEntityExt.getMenuId(), paasFormEntityExt);
                    }
                    if (Objects.equals(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), paasFormEntityExt.getBusinessType())) {
                        otherFormMap.put(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getAlias(), paasFormEntityExt);
                    }
                    if (Objects.equals(XbbRefTypeEnum.SALES_OPPORTUNITY.getCode(), paasFormEntityExt.getBusinessType())) {
                        otherFormMap.put(XbbRefTypeEnum.SALES_OPPORTUNITY.getAlias(), paasFormEntityExt);
                    }

                }

                Map<Long, PaasMenuEntity> menuMap = new HashMap<>(menuList.size());
                for (PaasMenuEntity item : menuList) {
                    menuMap.put(item.getId(), item);
                }
                Map<Long, PaasMenuEntity> workOrderMenuMap = new HashMap<>(workOrderMenuList.size());
                for (PaasMenuEntity item : workOrderMenuList) {
                    workOrderMenuMap.put(item.getId(), item);
                }
                // 获取工单的快捷新建表单
                quickList.addAll(getQuickFormList(workOrderMenuMap, quickNewListDTO, workOrderFormMap, quickNewList, otherFormMap));
                // 获取工单外的快捷新建表单
                quickList.addAll(getQuickFormList( menuMap, quickNewListDTO, formMap, quickNewList, otherFormMap));

            }
            List<WorkReportQuickNewPojo> workReportQuickNewList = new ArrayList<>();
            if (enableWorkReport) {
                UserVO userVO = quickNewListDTO.getLoginUser();
                UserEntity userEntity = new UserEntity();
                BeanUtil.copyProperties(userVO, userEntity);
                WorkReportSetVisibleRange workReportSetVisibleRange = workReportSetService.getVisibleRange(userEntity);
                if (workReportSetVisibleRange.getDayEnable()) {
                    WorkReportQuickNewPojo workReportQuickNewPojo = new WorkReportQuickNewPojo();
                    workReportQuickNewPojo.setBusinessType(XbbRefTypeEnum.WORKREPORT_DAILY.getCode());
                    workReportQuickNewPojo.setName(XbbRefTypeEnum.WORKREPORT_DAILY.getName());
                    workReportQuickNewList.add(workReportQuickNewPojo);
                }
                if (workReportSetVisibleRange.getWeekEnable()) {
                    WorkReportQuickNewPojo workReportQuickNewPojo = new WorkReportQuickNewPojo();
                    workReportQuickNewPojo.setBusinessType(XbbRefTypeEnum.WORKREPORT_WEEKLY.getCode());
                    workReportQuickNewPojo.setName(XbbRefTypeEnum.WORKREPORT_WEEKLY.getName());
                    workReportQuickNewList.add(workReportQuickNewPojo);
                }
                if (workReportSetVisibleRange.getMonthEnable()) {
                    WorkReportQuickNewPojo workReportQuickNewPojo = new WorkReportQuickNewPojo();
                    workReportQuickNewPojo.setBusinessType(XbbRefTypeEnum.WORKREPORT_MONTHLY.getCode());
                    workReportQuickNewPojo.setName(XbbRefTypeEnum.WORKREPORT_MONTHLY.getName());
                    workReportQuickNewList.add(workReportQuickNewPojo);
                }
            }
            if (!quickList.isEmpty()) {
                Collections.sort(quickList, new Comparator<QuickNewGetVO>() {
                    @Override
                    public int compare(QuickNewGetVO o1, QuickNewGetVO o2) {
                        //升序
                        return o1.getSort() - o2.getSort();
                    }
                });
            }
            quickNewListVO.setWorkReportQuickNewList(workReportQuickNewList);
            quickNewListVO.setQuickList(quickList);
        } catch (Exception e) {
            LOG.error("formService.quickNewList 获取快捷新建表单出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return quickNewListVO;
    }

    /**
     *
     * @param menuMap
     * @param quickNewListDTO
     * @param formMap
     * @param menuReturnList
     * @param otherFormMap
     * @return
     */
    private List<QuickNewGetVO> getQuickFormList(Map<Long, PaasMenuEntity> menuMap,
                                                 QuickNewListDTO quickNewListDTO, Map<Long, PaasFormEntityExt> formMap, List<MenuReturnPojo> menuReturnList, Map<String, PaasFormEntityExt> otherFormMap) throws XbbException {
        String[] webBlockMenuList = new String[] {
                XbbRefTypeEnum.CUSTOMER_DUPLICATE.getAlias(),
                XbbRefTypeEnum.SIGNIN.getAlias(),
        };
        Map<Long, MenuReturnPojo> menuReturnMap = new HashMap<>(menuReturnList.size());
        menuReturnList.forEach(item->{
            menuReturnMap.put(item.getMenuId(), item);
        });
        List<String> finalWebBlockMenuList = Arrays.asList(webBlockMenuList);
        Integer num = updatePackageRedisService.getUnusedNumPackageLimit(quickNewListDTO.getCorpid(), ValueAddedTypeEnum.CUSTOM_FORM_NUM);
        List<QuickNewGetVO> quickNewList = new ArrayList<>();
        for(MenuReturnPojo menuReturnPojo: menuReturnList) {
            Long menuId = menuReturnPojo.getMenuId();
            PaasMenuEntity item = menuMap.get(menuId);
            if (item == null) {
                continue;
            }

            if (Objects.equals(PlatFormEnum.WEB.getValue(),quickNewListDTO.getPlatform())
                    && finalWebBlockMenuList.contains(item.getAlias()) ){
                continue;
            }
            boolean isCustomer = false;
            boolean isOpportunity = false;
            if (Objects.equals(item.getAlias(), XbbRefTypeEnum.CUSTOMER.getAlias()) || Objects.equals(item.getAlias(), XbbRefTypeEnum.CUSTOMER_FOCUS.getAlias())
                    || Objects.equals(item.getAlias(), XbbRefTypeEnum.CUSTOMER_DEAL.getAlias()) || Objects.equals(item.getAlias(), XbbRefTypeEnum.CUSTOMER_FOLLOW.getAlias())
                    || Objects.equals(item.getAlias(), XbbRefTypeEnum.CUSTOMER_PUBLIC.getAlias()) || Objects.equals(item.getAlias(), XbbRefTypeEnum.CUSTOMER_RECYCLE.getAlias())
                    || Objects.equals(item.getAlias(), XbbRefTypeEnum.CUSTOMER_NEARBY.getAlias())) {
                isCustomer = true;
            }else if (Objects.equals(item.getAlias(), XbbRefTypeEnum.ALL_OPPORTUNITY.getAlias()) || Objects.equals(item.getAlias(), XbbRefTypeEnum.KEY_OPPORTUNITY.getAlias())) {
                isOpportunity = true;
            }
            Boolean include = formMap.containsKey(menuId) || formMap.containsKey(menuReturnPojo.getParentId()) || isCustomer || isOpportunity;
            if (include && !Objects.equals(MenuTypeEnum.MENU.getType(), item.getType())) {
                PaasFormEntityExt paasFormEntityExt = formMap.get(menuId);
                if (Objects.isNull(paasFormEntityExt) && !Objects.equals(0L, menuReturnPojo.getParentId())) {
                    paasFormEntityExt = formMap.get(menuReturnPojo.getParentId());
                } else if (isCustomer) {
                    paasFormEntityExt = otherFormMap.get(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getAlias());
                } else if (isOpportunity) {
                    paasFormEntityExt = otherFormMap.get(XbbRefTypeEnum.SALES_OPPORTUNITY.getAlias());
                }
                if (Objects.isNull(paasFormEntityExt)) {
                    continue;
                }
                QuickNewGetVO quickNewGetVO = new QuickNewGetVO();
                BeanUtil.copyProperties(item, quickNewGetVO);
                quickNewGetVO.setFormId(paasFormEntityExt.getId());
                quickNewGetVO.setName(item.getName());
                quickNewGetVO.setMenuId(menuId);
                quickNewGetVO.setSort(menuReturnPojo.getSort());
                if (Objects.equals(item.getSaasMark(), SaasMarkEnum.SAAS.getCode())) {
                    quickNewGetVO.setBusinessType(paasFormEntityExt.getBusinessType());
                    // 工单
                    if (Objects.equals(item.getAlias(), XbbRefTypeEnum.WORK_ORDER.getAlias())) {
                        quickNewGetVO.setBusinessType(XbbRefTypeEnum.WORK_ORDER.getCode());
                        quickNewGetVO.setSubBusinessType(XbbRefTypeEnum.WORK_ORDER.getCode());

                    }else if (Objects.equals(item.getAlias(), XbbRefTypeEnum.WORK_REPORT.getAlias())) {
                        // 工作报告
                        quickNewGetVO.setBusinessType(XbbRefTypeEnum.WORK_REPORT.getCode());
                        quickNewGetVO.setSubBusinessType(XbbRefTypeEnum.WORK_REPORT.getCode());
                    } else {
                        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByAlias(item.getAlias());
                        if (!Objects.equals(XbbRefTypeEnum.UNKNOWN.getCode(), xbbRefTypeEnum.getCode())) {
                            quickNewGetVO.setSubBusinessType(xbbRefTypeEnum.getCode());
                        }
                    }
                }
                if (Objects.equals(SaasMarkEnum.PAAS.getCode(), item.getSaasMark()) && num > 0) {
                    quickNewGetVO.setPackageLimit(1);
                    quickNewGetVO.setMessage(String.format(I18nMessageUtil.getMessage(PackageConstant.CUSTOM_FORM_SIZE_MESSAGE), num));
                }
                quickNewList.add(quickNewGetVO);
            } else if (Objects.equals(MenuTypeEnum.MENU.getType(), item.getType())) {
                QuickNewGetVO quickNewGetVO = new QuickNewGetVO();
                BeanUtil.copyProperties(item, quickNewGetVO);
                quickNewGetVO.setName(item.getName());
                quickNewGetVO.setMenuId(menuId);
                if (Objects.equals(item.getSaasMark(), SaasMarkEnum.SAAS.getCode())) {
                    Integer businessType = XbbRefTypeEnum.getByAlias(item.getAlias()).getCode();
                    quickNewGetVO.setBusinessType(businessType);
                    quickNewGetVO.setSubBusinessType(businessType);
                }
                quickNewGetVO.setSort(menuReturnMap.get(menuId).getSort());
                quickNewList.add(quickNewGetVO);
            }
        }
        return quickNewList;
    }

    /**
     * 查重表单名称
     *
     * @param formUpdateNameDTO
     * @return
     * @throws XbbException
     */
    private void repeatName(FormUpdateNameDTO formUpdateNameDTO) throws XbbException {
        String corpid = formUpdateNameDTO.getCorpid();
        Long menuId = formUpdateNameDTO.getMenuId();
        String name = formUpdateNameDTO.getName();
        if (Objects.nonNull(formUpdateNameDTO.getBusinessType()) && formUpdateNameDTO.getBusinessType() == XbbRefTypeEnum.WORK_ORDER.getCode()) {
            Map<String, Object> workOrderFormparam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            workOrderFormparam.put(StringConstant.CORPID, corpid);
            workOrderFormparam.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
            workOrderFormparam.put("menuId", menuId);
            List<WorkOrderFormEntity> workOrderList = workOrderFormModel.findEntitys(workOrderFormparam);
            if (Objects.isNull(workOrderList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
            }
            List<Long> templateIds = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            workOrderList.forEach(workOrderFormEntity -> templateIds.add(workOrderFormEntity.getTemplateId()));
            for(WorkOrderFormEntity workOrder : workOrderList){
                if(Objects.equals(workOrder.getName(),name)){
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.ATTR_NAME_DUPLICATE, name);
                }
            }

            Map<String, Object> workOrderTemplateparam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            workOrderTemplateparam.put(StringConstant.CORPID, corpid);
            workOrderTemplateparam.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
            workOrderTemplateparam.put("idIn", templateIds);
            List<WorkOrderTemplateEntityExt> workOrderTemplateEntityList = workOrderTemplateModel.findEntitys(workOrderTemplateparam);
            if (Objects.isNull(workOrderTemplateEntityList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
            }
            for(WorkOrderTemplateEntityExt workTemplate : workOrderTemplateEntityList){
                if(Objects.equals(workTemplate.getName(),name)){
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.ATTR_NAME_DUPLICATE, name);
                }
            }
        } else {
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(StringConstant.CORPID, corpid);
            param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
            param.put("menuId", menuId);
            List<PaasFormEntityExt> formList = paasFormModel.list(param);
            if (Objects.isNull(formList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
            }
            for(PaasFormEntityExt form : formList){
                if(Objects.equals(form.getName(),name)){
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.ATTR_NAME_DUPLICATE, name);
                }
            }
            if (formList.size() == 1) {
                PaasMenuEntity getBykey = paasMenuModel.getByKey(menuId, corpid);
                if(Objects.equals(getBykey.getName(), name)){
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.ATTR_NAME_DUPLICATE, name);
                }
            }
        }
    }


    @Override
    public FormUpdateNameVO updateName(FormUpdateNameDTO formUpdateNameDTO) throws XbbException {
        FormUpdateNameVO formUpdateNameVO = new FormUpdateNameVO();
        String corpid = formUpdateNameDTO.getCorpid();
        String name = formUpdateNameDTO.getName();
        String oldName;
        try {
            if (Objects.nonNull(formUpdateNameDTO.getBusinessType()) && formUpdateNameDTO.getBusinessType() == XbbRefTypeEnum.WORK_ORDER.getCode()) {
                WorkOrderFormEntityExt workOrderFormEntityExt = workOrderFormModel.getByKey(formUpdateNameDTO.getFormId(), corpid);
                if (Objects.isNull(workOrderFormEntityExt)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
                }
                oldName = workOrderFormEntityExt.getName();
                WorkOrderFormEntity updateForm = workOrderFormEntityExt;
                updateForm.setCorpid(corpid);
                updateForm.setId(formUpdateNameDTO.getFormId());
                updateForm.setName(name);
                updateForm.setNameEn(formUpdateNameDTO.getNameEn());
                workOrderFormModel.update(updateForm);
                Long templateId = workOrderFormEntityExt.getTemplateId();
                WorkOrderTemplateEntity workOrderTemplateEntity = new WorkOrderTemplateEntity();
                workOrderTemplateEntity.setCorpid(corpid);
                workOrderTemplateEntity.setId(templateId);
                workOrderTemplateEntity.setName(name);
                workOrderTemplateEntity.setNameEn(formUpdateNameDTO.getNameEn());
                workOrderTemplateModel.update(workOrderTemplateEntity);
            } else {
                PaasFormEntityExt paasFormEntityExt = paasFormModel.getByKey(formUpdateNameDTO.getFormId(), corpid);
                if (Objects.isNull(paasFormEntityExt)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
                }
                oldName = paasFormEntityExt.getName();
                PaasFormEntity updateForm = paasFormEntityExt;
                updateForm.setCorpid(corpid);
                updateForm.setId(formUpdateNameDTO.getFormId());
                updateForm.setName(name);
                updateForm.setNameEn(formUpdateNameDTO.getNameEn());
                paasFormModel.update(updateForm);
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put(StringConstant.CORPID, corpid);
                param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                param.put("menuId", formUpdateNameDTO.getMenuId());
                List<PaasFormEntityExt> formList = paasFormModel.list(param);
                if (Objects.isNull(formList)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
                }
                if (formList.size() == 1) {
                    PaasMenuEntity paasMenuEntity = new PaasMenuEntity();
                    paasMenuEntity.setId(formUpdateNameDTO.getMenuId());
                    paasMenuEntity.setCorpid(corpid);
                    paasMenuEntity.setName(name);
                    paasMenuEntity.setNameEn(formUpdateNameDTO.getNameEn());
                    paasMenuModel.update(paasMenuEntity);
                }
            }
        } catch (Exception e) {
            LOG.error("formService.updateName 出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        // 记录日志
        String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_UPDATE_FORM_NAME), formUpdateNameDTO.getLoginUserName(), oldName, name);
        mongoLogHelp.buildLog(corpid, formUpdateNameDTO.getUserId(), formUpdateNameDTO.getLoginUserName(), OperateModuleTypeEnum.PAAS_FORM, OperateTypeEnum.EDIT,
                formUpdateNameDTO.getFormId().toString(), name, memo, formUpdateNameDTO.getHttpHeader());
        return formUpdateNameVO;
    }


    @Override
    public List<PaasFormEntityExt> getEnableFormList(UserVO loginUser, Integer businessType, Long appId, Integer distributorMark) throws XbbException {
        return formTemplateModel.getEnableFormList(loginUser.getCorpid(), loginUser, businessType, appId, distributorMark);
    }


    @Override
    public AllAppFormListVO getAllAppFormList(AllAppFormListDTO allAppFormListDTO) throws XbbException {
        AllAppFormListVO allAppFormListVO = new AllAppFormListVO();
        try {
            Map<String, Object> param = BeanUtil.convertBean2Map(allAppFormListDTO, true);
            param.put("orderByStr", "sort asc");
            List<PaasAppEntity> appList = paasAppModel.list(param);
            if (Objects.isNull(appList)) {
                allAppFormListVO.setAppList(new ArrayList<>());
                return allAppFormListVO;
            }
            Long workOrderAppId = null;
            Iterator<PaasAppEntity> iterator = appList.iterator();
            while (iterator.hasNext()) {
                PaasAppEntity paasAppEntity = iterator.next();
                String alias = paasAppEntity.getAlias();
                if (Objects.equals(alias, SystemAppMenuEnum.GROUP_MESSAGE.getAlias())
                        || Objects.equals(alias, SystemAppMenuEnum.CALL_CENTER.getAlias()) || Objects.equals(SystemAppMenuEnum.SEARCH_CUSTOMER.getAlias(), alias)) {
                    iterator.remove();
                }
                // 关联工单
                if (Objects.equals(paasAppEntity.getAlias(), XbbRefTypeEnum.WORK_ORDER.getAlias())) {
                    workOrderAppId = paasAppEntity.getId();
                }
            }
            Boolean distributorEnable = paasAppService.validateAppEnable(null, XbbRefTypeEnum.DISTRIBUTOR.getAlias(), SaasMarkEnum.SAAS.getCode(), allAppFormListDTO.getCorpid());
            param.clear();
            param = BeanUtil.convertBean2Map(allAppFormListDTO, true);
            // 菜单id为0为bi表单，无需搜出
            param.put("negMenuId", 0);
            param.put("orderByStr", "update_time desc");
            if (!distributorEnable) {
                param.put("distributorMark", DistributorMarkEnum.OTHER.getCode());
            }
            List<PaasFormEntityExt> formList = paasFormModel.list(param);
            if (Objects.isNull(formList )) {
                allAppFormListVO.setAppList(new ArrayList<>());
                return allAppFormListVO;
            }
            //存在工单中心时 添加工单列表页
            formList.addAll(getWorkOrderList(allAppFormListDTO.getCorpid(), workOrderAppId));
            Map<Long, List<FormSimpleListVO>> formMap = new HashMap<>(formList.size());

            List<Long> excludeFormId = allAppFormListDTO.getExcludeFormId();
            List<Integer> unSeeFormList = packageHelp.getUnSeeFormList(allAppFormListDTO.getCorpid());
            boolean clueConvert = Objects.nonNull(allAppFormListDTO.getClueConvert());
            for (PaasFormEntityExt paasFormEntityExt : formList) {
                if (clueConvert && !Objects.equals(paasFormEntityExt.getBusinessType(), XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode())) {
                    // 线索转换设置这里，只需要客户的表单，转换已有客户和字段映射共用此处
                    continue;
                }
                if (clueConvert &&  paasFormEntityExt.getDistributorMark()!=null && paasFormEntityExt.getDistributorMark()==1) {
                    // 线索转换设置这里，只需要客户的表单，转换已有客户和字段映射共用此处
                    continue;
                }
                // 过滤掉自己以及已经选了的字段
                Long formId = paasFormEntityExt.getId();
                if (Objects.equals(formId, allAppFormListDTO.getFormId())
                        || excludeFormId.contains(formId)) {
                    continue;
                }
                if (Objects.equals(1, allAppFormListDTO.getBusinessRuleFlag()) && !FormUtil.haveUserPermission(paasFormEntityExt.getBusinessType(), paasFormEntityExt.getSaasMark(), paasFormEntityExt.getDistributorMark())) {
                    // 业务规则不可使用的表单，跳出循环
                    continue;
                }
                if (Objects.equals(BasicConstant.TWO, allAppFormListDTO.getBusinessRuleFlag())
                        && !FormUtil.haveWorkflowPermission(paasFormEntityExt.getBusinessType(), paasFormEntityExt.getSaasMark(), paasFormEntityExt.getDistributorMark())
                        && (Objects.equals(DistributorMarkEnum.DISTRIBUTOR.getCode(), paasFormEntityExt.getDistributorMark())
                        || Objects.equals(paasFormEntityExt.getSaasMark(), SaasMarkEnum.SAAS.getCode()) && !ProcessSaasFormEnum.containsBusinessType(paasFormEntityExt.getBusinessType()))) {
                    // 工作流去掉经销商表单和不支持审批的表单以及不支持业务规则的表单
                    // 工作流不可使用的表单，跳出循环
                    continue;
                }
                // 过滤掉bi的一些表单
                BIProductEnum biProductEnum = BIProductEnum.getByCode(paasFormEntityExt.getBusinessType());
                if (Objects.nonNull(biProductEnum) ||
                        Objects.equals(paasFormEntityExt.getBusinessType(), XbbRefTypeEnum.CONTRACT_PERFORMANCE.getCode())) {
                    continue;
                }
                // 过滤掉周报，日报，月报
                WorkReportEnum workReportEnum = WorkReportEnum.getByCode(paasFormEntityExt.getBusinessType());
                if (Objects.nonNull(workReportEnum)) {
                    continue;
                }
                // 过滤预收款、库存产品
                if (BLOCK_LIST.contains(paasFormEntityExt.getBusinessType())) {
                    continue;
                }
                // 如果在标准版下资金的其他支出单、其他收入单、资金调拨单需要过滤掉
                if (unSeeFormList.contains(paasFormEntityExt.getBusinessType())) {
                    continue;
                }

                Long appId = paasFormEntityExt.getAppId();
                FormSimpleListVO formSimpleListVO = new FormSimpleListVO();
                BeanUtil.copyProperties(paasFormEntityExt, formSimpleListVO);
                formSimpleListVO.setFormId(formId);
                if (formMap.containsKey(appId)) {
                    List<FormSimpleListVO> formSimpleListVOS = formMap.get(appId);
                    formSimpleListVOS.add(formSimpleListVO);
                    formMap.put(appId, formSimpleListVOS);
                } else {
                    List<FormSimpleListVO> formSimpleListVOS = new ArrayList<>();
                    formSimpleListVOS.add(formSimpleListVO);
                    formMap.put(appId, formSimpleListVOS);
                }
            }

            List<FormResultListVO> result = new ArrayList<>();
            appList.forEach(item->{
                List<FormSimpleListVO> formSimpleListVOS = formMap.get(item.getId());
                if (CollectionsUtil.isNotEmpty(formSimpleListVOS)) {
                    FormResultListVO formResultListVO = new FormResultListVO();
                    BeanUtil.copyProperties(item, formResultListVO);
                    formResultListVO.setAppId(item.getId());
                    formResultListVO.setAppName(item.getName());
                    formResultListVO.setFormList(formSimpleListVOS);
                    result.add(formResultListVO);
                }
            });

            // 关联产品联动表单特殊处理，仅限关联产品与关联产品联动使用
            if (DefaultTypeEnum.PRODUCT_DATA_RELY.getAlias().equals(allAppFormListDTO.getDefaultType())) {
                linkProductRelyFormFilter(result, allAppFormListDTO);
            }
            allAppFormListVO.setAppList(result);
        } catch (Exception e) {
            LOG.error("PaasFormServiceImpl.getAllAppFormList  出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return allAppFormListVO;
    }

    @Override
    public AllAppFormListVO getAppFormList(AppFormListDTO appFormListDTO) throws XbbException {
        try {
            String corpid = appFormListDTO.getCorpid();
            AllAppFormListVO allAppFormListVO = new AllAppFormListVO();
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(StringConstant.CORPID, corpid);
            param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
            param.put("enable", 1);
            param.put("orderByStr", "sort asc");
            List<PaasAppEntity> appList = paasAppModel.list(param);
            if (CollectionsUtil.isEmpty(appList)) {
                allAppFormListVO.setAppList(new ArrayList<>());
                return allAppFormListVO;
            }
            Map<Long, String> appId2AliasMap = new HashMap<>();
            boolean isSharePermission = Objects.equals(appFormListDTO.getFilterType(), FormListFilterTypeEnum.SHARE_PERMISSION_LIST.getType())
                    || Objects.equals(appFormListDTO.getFilterType(), FormListFilterTypeEnum.SHARE_PERMISSION_ADD.getType());
            List<String> supportSystemAppList = new ArrayList<>();
            handleSharePermission(appFormListDTO.getFilterType(), corpid, appList, supportSystemAppList);
            Long workOrderAppId = null;
            Iterator<PaasAppEntity> iterator = appList.iterator();
            while (iterator.hasNext()) {
                PaasAppEntity paasAppEntity = iterator.next();
                String alias = paasAppEntity.getAlias();
                if (Objects.equals(alias, SystemAppMenuEnum.GROUP_MESSAGE.getAlias())
                        || Objects.equals(alias, SystemAppMenuEnum.CALL_CENTER.getAlias()) || Objects.equals(SystemAppMenuEnum.SEARCH_CUSTOMER.getAlias(), alias)) {
                    iterator.remove();
                    continue;
                }
                if (isSharePermission) {
                    appId2AliasMap.put(paasAppEntity.getId(), paasAppEntity.getAlias());
                }
                // 关联工单
                if (Objects.equals(paasAppEntity.getAlias(), XbbRefTypeEnum.WORK_ORDER.getAlias())) {
                    workOrderAppId = paasAppEntity.getId();
                }
            }

            param.clear();
            param.put(StringConstant.CORPID, corpid);
            param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
            param.put("enable", 1);
            // 菜单id为0为bi表单，无需搜出
            param.put("negMenuId", 0);
            param.put("orderByStr", "update_time desc");
            List<PaasFormEntityExt> formList = paasFormModel.list(param);
            if (CollectionsUtil.isEmpty(formList)) {
                allAppFormListVO.setAppList(new ArrayList<>());
                return allAppFormListVO;
            }
            //存在工单中心时 添加工单列表页
            formList.addAll(getWorkOrderList(corpid, workOrderAppId));
            Map<Long, List<FormSimpleListVO>> formMap = new HashMap<>(formList.size());

            List<Integer> unSeeFormList = packageHelp.getUnSeeFormList(corpid);
            for (PaasFormEntityExt paasFormEntityExt : formList) {

                // 过滤掉自己以及已经选了的字段
                Long formId = paasFormEntityExt.getId();
                Long appId = paasFormEntityExt.getAppId();
                // 过滤掉bi的一些表单
                BIProductEnum biProductEnum = BIProductEnum.getByCode(paasFormEntityExt.getBusinessType());
                if (Objects.nonNull(biProductEnum) ||
                        Objects.equals(paasFormEntityExt.getBusinessType(), XbbRefTypeEnum.CONTRACT_PERFORMANCE.getCode())) {
                    continue;
                }

                // 过滤预收款、库存产品
                if (BLOCK_LIST.contains(paasFormEntityExt.getBusinessType())) {
                    continue;
                }
                // 如果在标准版下资金的其他支出单、其他收入单、资金调拨单需要过滤掉
                if (unSeeFormList.contains(paasFormEntityExt.getBusinessType())) {
                    continue;
                }
                //共享权限下 进行过滤
                if (isSharePermission) {
                    String alias = appId2AliasMap.get(appId);
                    if (Objects.equals(SaasMarkEnum.SAAS.getCode(), paasFormEntityExt.getSaasMark())) {
                        List<Integer> supportListByAppAlias = ShareSupportFormEnum.getSupportListByAppAlias(alias);
                        if (!supportListByAppAlias.contains(paasFormEntityExt.getBusinessType())
                                || ShareSupportFormEnum.getNonsupportList().contains(paasFormEntityExt.getBusinessType())) {
                            continue;
                        }
                    } else {
                        if (Objects.equals(alias, SystemAppMenuEnum.COOL_APP.getAlias())) {
                            // 酷应用的直接跳过不加
                            continue;
                        }
                    }
                }

                FormSimpleListVO formSimpleListVO = new FormSimpleListVO();
                BeanUtil.copyProperties(paasFormEntityExt, formSimpleListVO);
                formSimpleListVO.setFormId(formId);
                if (formMap.containsKey(appId)) {
                    List<FormSimpleListVO> formSimpleListVOS = formMap.get(appId);
                    formSimpleListVOS.add(formSimpleListVO);
                    formMap.put(appId, formSimpleListVOS);
                } else {
                    List<FormSimpleListVO> formSimpleListVOS = new ArrayList<>();
                    formSimpleListVOS.add(formSimpleListVO);
                    formMap.put(appId, formSimpleListVOS);
                }
            }

            List<FormResultListVO> result = new ArrayList<>();
            appList.forEach(item -> {
                List<FormSimpleListVO> formSimpleListVOS = formMap.get(item.getId());
                if (CollectionsUtil.isNotEmpty(formSimpleListVOS)) {
                    FormResultListVO formResultListVO = new FormResultListVO();
                    BeanUtil.copyProperties(item, formResultListVO);
                    formResultListVO.setAppId(item.getId());
                    formResultListVO.setAppName(item.getName());
                    formResultListVO.setFormList(formSimpleListVOS);
                    result.add(formResultListVO);
                }
            });
            allAppFormListVO.setAppList(result);
            return allAppFormListVO;
        }catch (Exception e) {
            LOG.error("PaasFormServiceImpl.getAppFormList  出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    /**
     * 获取supportSystemAppList(支持的Saas appIds) + 拿到无需过滤的appIds(有规则并且被关闭的应用)
     * 注：有规则时，应用关闭会展示，表单关闭不会展示。
     *
     * @param filterType
     * @param corpid
     * @param appList
     * @param supportSystemAppList
     * @return
     */
    private void handleSharePermission(String filterType, String corpid, List<PaasAppEntity> appList, List<String> supportSystemAppList) {

        //关闭的应用
        Map<String, Object> params = new HashMap<>();
        params.put("corpid", corpid);
        params.put("enable", EnableEnum.CLOSE.getCode());
        params.put("del", DelEnum.NORMAL.getDel());
        List<PaasAppEntity> unEnableAppList = paasAppModel.list(params);
        List<Long> unEnableAppIdList = new ArrayList<>();
        //获取支持的应用
        supportSystemAppList.addAll(ShareSupportFormEnum.getSupportAppList());
        for (PaasAppEntity unEnableApp : unEnableAppList) {
            supportSystemAppList.remove(unEnableApp.getAlias());
            unEnableAppIdList.add(unEnableApp.getId());
        }

        if (Objects.equals(filterType, FormListFilterTypeEnum.SHARE_PERMISSION_ADD.getType())) {
            //列表入口的筛选需要展示有规则但被关闭的应用，添加入口不能展示被关闭的应用
            return;
        }

        //应用被关闭的规则
        params.clear();
        params.put("corpid", corpid);
        params.put("appIdIn", unEnableAppIdList);
        params.put("del", DelEnum.NORMAL.getDel());
        List<ShareRuleEntity> shareRuleEntityList = shareRuleModel.findEntitys(params);
        //获取不需要过滤的appIds
        Set<Long> dontFilterAppIds = new HashSet<>();
        if (!shareRuleEntityList.isEmpty()) {
            shareRuleEntityList.forEach(item -> {
                dontFilterAppIds.add(item.getAppId());
            });
        }
        params.clear();
        params.put(StringConstant.CORPID, corpid);
        params.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        params.put("idIn", dontFilterAppIds);
        List<PaasAppEntity> donFilterAppList = paasAppModel.list(params);
        appList.addAll(donFilterAppList);
    }

    /**
     * 关联产品联动表单特殊处理
     *
     * @param appList           表单数据
     * @param allAppFormListDTO 参数
     */
    private void linkProductRelyFormFilter(List<FormResultListVO> appList, AllAppFormListDTO allAppFormListDTO) throws XbbException {
        Long formId = allAppFormListDTO.getFormId();
        PaasFormEntityExt paasFormEntityExt = paasFormModel.getByKey(formId, allAppFormListDTO.getCorpid());
        Integer businessType;
        // 如果查询的表单业务类型为null或者0，则认为该表单是工单
        if (Objects.isNull(paasFormEntityExt) || Objects.isNull(paasFormEntityExt.getBusinessType()) || BasicConstant.ZERO.equals(paasFormEntityExt.getBusinessType())) {
            businessType = XbbRefTypeEnum.WORK_ORDER.getCode();
        } else {
            businessType = paasFormEntityExt.getBusinessType();
        }
        List<LinkProductRelyEnum> linkProductRelyEnums = LinkProductRelyEnum.getByBuinessType(businessType);
        List<Integer> sourceBuinessType = new ArrayList<>();
        linkProductRelyEnums.forEach(item -> {
            sourceBuinessType.add(item.getSourceBusinessType());
        });
        Boolean isJxcUse = paasAppService.validateAppEnable(null, XbbRefTypeEnum.JXC.getAlias(), SaasMarkEnum.SAAS.getCode(), allAppFormListDTO.getCorpid());
        PaasAppEntity paasAppEntity = paasAppModel.getByAlias(XbbRefTypeEnum.JXC.getAlias(), allAppFormListDTO.getCorpid());
        Iterator<FormResultListVO> appIterator = appList.iterator();
        while (appIterator.hasNext()) {
            FormResultListVO formResultListVO = appIterator.next();
            List<FormSimpleListVO> formList = formResultListVO.getFormList();
            // 进销存未开启
            if (Objects.nonNull(paasAppEntity) && Objects.equals(formResultListVO.getAppId(), paasAppEntity.getId()) && !isJxcUse) {
                appIterator.remove();
                continue;
            }
            if (CollectionsUtil.isEmpty(formList)) {
                appIterator.remove();
                continue;
            }
            formList.removeIf(formSimpleListVO -> !sourceBuinessType.contains(formSimpleListVO.getBusinessType()));
            if (CollectionsUtil.isEmpty(formResultListVO.getFormList())) {
                appIterator.remove();
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public FormDeleteVO delete(FormDeleteDTO formDeleteDTO) throws XbbException {
        String corpid = formDeleteDTO.getCorpid();
        FormDeleteVO formDeleteVO = new FormDeleteVO();
        PaasFormEntity paasFormEntity = new PaasFormEntity();
        try {
            UserVO userVO = formDeleteDTO.getLoginUser();
            if (!userVO.isAdminOrBoss() && !userVO.getPermSet().contains(ProPermissionAliasEnum.FORM_SET_DELETE.getAlias())) {
                throw new XbbException(ProErrorCodeEnum.API_ERROR_260001 );
            }
            Long formId = formDeleteDTO.getFormId();
            Integer saasMark = formDeleteDTO.getSaasMark();
            IndexTypeEnum indexTypeEnum = indexTypeModel.getIndexType(corpid, formDeleteDTO.getBusinessType(), saasMark);


            // 校验业务规则
            Integer feeType = businessRuleInfoService.validateBusinessRules(corpid, formId, formDeleteDTO.getBusinessType());
            // 判断表单数据是否存在
            BoolQueryBuilder boolQueryBuilder = boolQuery();
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
            if (Objects.equals(formDeleteDTO.getBusinessType(), XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode())) {
                // bug:20431
                boolQueryBuilder.filter(termsQuery("del", Arrays.asList(DelEnum.NORMAL.getDel(), DelEnum.DELETE.getDel())));
            } else {
                boolQueryBuilder.filter(termQuery("del", DelEnum.NORMAL.getDel()));
            }
            boolQueryBuilder.filter(termQuery("formId", formDeleteDTO.getFormId()));
            boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,indexTypeEnum.getType()));
            sourceBuilder.query(boolQueryBuilder);
            SearchRequest searchRequest = new SearchRequest(indexTypeEnum.getIndex());
            searchRequest.source(sourceBuilder);
            long count = xbbElasticsearchRestTemplate.count(searchRequest, PaasFormDataEntityExt.class);
            if (count > 0) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.HAS_FORM_DATA);
            }
            // 流程表单数据
            boolean isOpenWorkflow = commonHelp.isOpenWorkFlow(corpid);
            if (isOpenWorkflow) {
                paasFormHelp.validateFormHasWorkflow(corpid, formDeleteDTO.getAppId(), formDeleteDTO.getMenuId(), formId);
            } else {
                Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                params.put("appId", formDeleteDTO.getAppId());
                params.put("menuId", formDeleteDTO.getMenuId());
                params.put("formId", formDeleteDTO.getFormId());
                params.put("corpid", formDeleteDTO.getCorpid());
                params.put("del", 0);
                Integer taskCount = paasProcessTaskModel.getEntitysCount(params);
                if (taskCount > 0) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.HAS_PROCESS_DATA);
                }
            }

            // 获取表单
            paasFormEntity = paasFormModel.getByKey(formDeleteDTO.getFormId(), corpid);
            if (Objects.isNull(paasFormEntity)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
            }
            if (!Objects.equals(paasFormEntity.getName(), formDeleteDTO.getFormName())) {
                throw new XbbException(ProErrorCodeEnum.API_ERROR_260002);
            }

            if (Objects.equals(SaasMarkEnum.SAAS.getCode(), saasMark)) {
                // 判断表单
                Map<String, Object> param = BeanUtil.convertBean2Map(formDeleteDTO, true);
                List<PaasFormEntityExt> formList = paasFormModel.list(param);
                if (Objects.isNull(formList)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
                }
                if (formList.size() == 1) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_ONLY_ONE);
                }
                // 至少一个启用的表单
                boolean noEnableForm = true;
                for (PaasFormEntity entity : formList) {
                    if (Objects.equals(entity.getId(), paasFormEntity.getId())) {
                        continue;
                    }
                    if (Objects.equals(entity.getEnable(), BasicConstant.IS_USE)) {
                        noEnableForm = false;
                        break;
                    }
                }
                if (noEnableForm) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_ONLY_ONE_ENABLE);
                }
                // 校验客户和合同是否设置了智能助手
                if (Objects.equals(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), paasFormEntity.getBusinessType())
                    || Objects.equals(XbbRefTypeEnum.CONTRACT.getCode(), paasFormEntity.getBusinessType())) {
                    param.clear();
                    param.put(StringConstant.CORPID, corpid);
                    param.put(StringConstant.FORM_ID, formId);
                    param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                    List<AiAssistantEntity> aiAssistantList = aiAssistantModel.findEntitys(param);
                    if (CollectionsUtil.isNotEmpty(aiAssistantList)) {
                        throw new XbbException(ProErrorCodeEnum.API_ERROR_260020);
                    }
                }

            } else if (Objects.equals(SaasMarkEnum.PAAS.getCode(), saasMark)) {
                MenuFormDelDTO menuFormDelDTO = new MenuFormDelDTO();
                BeanUtil.copyProperties(formDeleteDTO, menuFormDelDTO);
                paasMenuService.deleteFormMenu(menuFormDelDTO);
            }
            // 删除表单 -> 原先只删除主业务表单，现在要把这个主业务表单对应的子表单也删除掉
            List<Long> subProductFormIds = new ArrayList<>();
            if (BIProductReformEnum.getAllBusinessTypes().contains(paasFormEntity.getBusinessType())) {
                List<PaasFormRefEntity> paasFormRefEntities = paasFormRefModel.getListByMainFormId(paasFormEntity.getId(), corpid);
                if (CollectionsUtil.isNotEmpty(paasFormRefEntities)) {
                    List<Long> paasFormRefIds = paasFormRefEntities.stream().map(PaasFormRefEntity::getId).collect(Collectors.toList());
                    subProductFormIds = paasFormRefEntities.stream().map(PaasFormRefEntity::getFormId).collect(Collectors.toList());
                    paasFormRefModel.deleteBatch(paasFormRefIds, corpid);
                }
            }
            List<Long> deleteIds = new ArrayList<>();
            deleteIds.add(paasFormEntity.getId());
            if (CollectionsUtil.isNotEmpty(subProductFormIds)) {
                deleteIds.addAll(subProductFormIds);
            }
            paasFormModel.deleteBatch(deleteIds, corpid);
            //paasFormModel.delete(paasFormEntity.getId(), corpid);

            FormExplainDeleteDTO formExplainDeleteDTO = new FormExplainDeleteDTO();
            BeanUtil.copyProperties(formDeleteDTO, formExplainDeleteDTO);
            paasFormExplainService.delete(formExplainDeleteDTO);

            // 删除客户名称和客户电话的配置(表单配置表)
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("formId", paasFormEntity.getId());
            param.put("businessType", paasFormEntity.getBusinessType());
            param.put("configIn", Arrays.asList(FormConfigEnum.CUSTOMER_NAME_REPEAT_TYPE.getConfig(), FormConfigEnum.CUSTOMER_PHONE_REPEAT_TYPE.getConfig(), FormConfigEnum.CLUE_NAME_REPEAT_TYPE.getConfig(), FormConfigEnum.CLUE_PHONE_REPEAT_TYPE.getConfig()));
            param.put("updateTime", DateTimeUtil.getInt());
            param.put("del", DelEnum.DELETE.getDel());
            formConfigModel.updateRepeatType(param);

            // 删除表单时，需要判断该表单其他设置属性
            deleteOtherByDeleteForm(formId, corpid, formDeleteDTO.getBusinessType());
            deleteShareRule(formDeleteDTO.getAppId(), formId, corpid);

            String key = corpid + "_"+ ValueAddedTypeEnum.CUSTOM_FORM_NUM.getType();
            paasRedisHelper.removeValue(RedisPrefixConstant.VALUE_ADDED, key);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("PaasFormServiceImpl.delete  出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        String userName = formDeleteDTO.getLoginUserName();
        // 记录日志
        String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_DELETE_FORM), userName, paasFormEntity.getName());
        mongoLogHelp.buildLog(corpid, formDeleteDTO.getUserId(), userName, OperateModuleTypeEnum.PAAS_FORM, OperateTypeEnum.DELETE,
                paasFormEntity.getId().toString(), paasFormEntity.getName(), memo, formDeleteDTO.getHttpHeader());

        return formDeleteVO;
    }

    /**
     * 删除表单时也删除该表单关联的共享规则
     * @param appId
     * @param formId
     * @param corpid
     */
    private void deleteShareRule(Long appId, Long formId, String corpid) {
        Map<String, Object> param = new HashMap<>();
        param.put("corpid", corpid);
        param.put("appId", appId);
        param.put("formId", formId);
        List<ShareRuleEntity> entitys = shareRuleModel.findEntitys(param);
        if (entitys.isEmpty()) {
            return;
        }
        List<Long> delIds = entitys.stream().map(ShareRuleEntity::getId).collect(Collectors.toList());
        shareRuleModel.deleteBatch(delIds, corpid);
        sharePermissionSetUserModel.deleteByFormId(corpid,formId);
    }


    /**
     * 校验关联数据的主键字段
     * @param fieldAttrEntity
     * @param attrName
     * @throws XbbException
     */
    private LinkDataNumCheckPojo validateLinkKey(FieldAttrEntity fieldAttrEntity, String attrName, LinkDataNumCheckPojo linkDataNumCheckPojo) throws XbbException {
        if (Objects.equals(FieldTypeEnum.LINK_DATA.getType(), fieldAttrEntity.getFieldType()) || Objects.equals(FieldTypeEnum.LINK_DATA_MULTI.getType(), fieldAttrEntity.getFieldType())) {
            LinkInfoPojo linkInfoPojo = fieldAttrEntity.getLinkInfo();
            if (StringUtil.isEmpty(linkInfoPojo.getLinkKey())) {
                throw new XbbException(ProErrorCodeEnum.API_ERROR_260004, String.format(ProErrorCodeEnum.API_ERROR_260004.getMsg(), attrName));
            }
            if (Objects.equals(FieldTypeEnum.LINK_DATA.getType(), fieldAttrEntity.getFieldType())) {
                Integer linkDataNum = linkDataNumCheckPojo.getLinkDataNum();
                linkDataNum ++;
                linkDataNumCheckPojo.setLinkDataNum(linkDataNum);
            } else {
                Integer linkDataMultiNum = linkDataNumCheckPojo.getLinkDataMultiNum();
                linkDataMultiNum ++;
                linkDataNumCheckPojo.setLinkDataMultiNum(linkDataMultiNum);
            }
        }
        return linkDataNumCheckPojo;
    }

    /**
     * 校验关联数据的条件数量
     * @param fieldAttrEntity
     * @param attrName
     * @return
     * @author xingxing.xiao
     * @date 2020/07/28 15:11
     */
    private void validateLinkInfoCondition (FieldAttrEntity fieldAttrEntity, String attrName) throws XbbException {
        if (Objects.equals(FieldTypeEnum.LINK_DATA.getType(), fieldAttrEntity.getFieldType()) || Objects.equals(FieldTypeEnum.LINK_DATA_MULTI.getType(), fieldAttrEntity.getFieldType())) {
            LinkInfoPojo linkInfoPojo = fieldAttrEntity.getLinkInfo();
            if (StringUtil.isEmpty(linkInfoPojo.getLinkKey())) {
                throw  new XbbException(ProErrorCodeEnum.API_ERROR_260004, String.format(ProErrorCodeEnum.API_ERROR_260004.getMsg(), attrName));
            }
            if (linkInfoPojo.getCondition().size() > CONDITION_NUM) {
                throw new XbbException(ProErrorCodeEnum.API_ERROR_260025, ProErrorCodeEnum.API_ERROR_260025.getMsg(), attrName);
            }
        }
    }

    /**
     * 获取工单表单数据
     * @param corpid
     * @param appId
     * @return 工单表单列表
     * @throws XbbException
     */
    private List<PaasFormEntityExt> getWorkOrderList(String corpid, Long appId) throws XbbException {
        List<PaasFormEntityExt> formList = new ArrayList<>();
        try {
            if (appId == null) {
                return formList;
            }
            Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            map.put("appId", appId);
            map.put("corpid", corpid);
            map.put("enable", 1);
            map.put("del", DelEnum.NORMAL.getDel());
            List<WorkOrderFormEntity> explainEntities = workOrderFormModel.findEntitys(map);
            BeanUtil.copyPropertiesList(explainEntities, formList, PaasFormEntityExt.class);
            formList.forEach(workOrderEntity -> {
                if (Objects.equals(LocaleContextHolder.getLocale().getLanguage(), I18nStringConstant.ENGLISH_LANGUAGE)) {
                    String name = workOrderEntity.getName();
                    String nameEn = workOrderEntity.getNameEn();
                    workOrderEntity.setName(name);
                    workOrderEntity.setNameEn(nameEn);
                }
                workOrderEntity.setSaasMark(SaasMarkEnum.SAAS.getCode());
                workOrderEntity.setBusinessType(XbbRefTypeEnum.WORK_ORDER.getCode());
                workOrderEntity.setDistributorMark(DistributorMarkEnum.OTHER.getCode());
            });
        } catch (XbbException e) {
            LOG.error("PaasFormServiceImpl.getAllAppFormList  出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        } catch (Exception e) {
            LOG.error("PaasFormServiceImpl.getAllAppFormList  出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return formList;
    }

    /**
     * 获取工单表单数据
     * @param corpid
     * @param formList 工单表单列表
     * @return 工单表单列表
     * @throws XbbException
     */
    private List<PaasFormExplainEntityExt> getWorkOrderExplainList(String corpid, List<PaasFormEntityExt> formList) throws XbbException {
        List<PaasFormExplainEntityExt> formExplainList = new ArrayList<>();
        try {
            if (formList == null || formList.isEmpty()) {
                return formExplainList;
            }
            List<Long> formIdIn = new ArrayList<>();
            formList.forEach(item->{
                formIdIn.add(item.getId());
            });
            Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);

            map.put("formIdIn", formIdIn);
            map.put("corpid", corpid);
            map.put("del", 0);
            List<WorkOrderExplainEntity> explainEntities = workOrderExplainModel.findEntitys(map);
            explainEntities.forEach(item -> {
                PaasFormExplainEntityExt paasFormExplainEntityExt = new PaasFormExplainEntityExt(item.getId(), item.getCorpid(), item.getAppId(), item.getMenuId(), item.getFormId(),
                        1, item.getExplains(), item.getCreatorId(), item.getAddTime(), item.getUpdateTime(), item.getDel(),SaasMarkEnum.SAAS.getCode(), DistributorMarkEnum.OTHER.getCode(), XbbRefTypeEnum.WORK_ORDER.getCode(),
                        JSON.parseArray(item.getExplains()) );
                formExplainList.add(paasFormExplainEntityExt);
            });

        } catch (Exception e) {
            LOG.error("PaasFormServiceImpl.getWorkOrderExplainList  出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return formExplainList;
    }

    /**
     * 格式化saas应用菜单/表单模块权限，从数据库存储格式 ==> List<PermissionComplexTermPojo>
     * @param businessType saas业务类型
     * @param role 角色实体
     * @return List<PermissionComplexTermPojo>
     */
    private FormRoleDetailVO formatSaasModulePermission(String corpid, Integer businessType, RoleEntity role) throws XbbException {
        FormRoleDetailVO formRoleDetailVO = new FormRoleDetailVO();
        List<PermissionComplexTermPojo> termPermissions = new ArrayList<>();
        Integer dataPermission = 1;
        if (businessType == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002, MessageConstant.ABNORMAL_PARAMETER, "businessType");
        }
        // 通过businessType 获取 alias 和 proPermissionId
        String businessAlias = XbbRefTypeEnum.getByCode(businessType).getAlias();
        ProPermissionEntity proPermission = proPermissionModel.getByAlias(businessAlias);
        if (proPermission == null) {
            formRoleDetailVO.setDataPermission(dataPermission);
            formRoleDetailVO.setPermission(termPermissions);
            return formRoleDetailVO;
        }

        // SAAS应用，传输的appId为SAAS应用对应proPermissionId
        Map<String, Object> params = new HashMap<>(16);
        params.put("parentId", proPermission.getId());
        params.put("del", 0);
        params.put("orderByStr", "sort");
        List<ProPermissionEntity> modulePerms = proPermissionModel.findEntitys(params);

        termPermissions = PermissionHelp.initDefaultSaasModulePermission(modulePerms);
        cloudCodeHelp.addCloudCodePermission(corpid, businessAlias, termPermissions);
        // 已设置的权限列表
        Set<Integer> permissionIdsSet = role.getPermissionIdsSet();

        Set<String> dynamicPermissionSet = cloudCodeHelp.getDynamicPermissionSet(role.getDynamicPermissions());

        if (permissionIdsSet != null && permissionIdsSet.size() > 0) {
            for (PermissionComplexTermPojo termPojo : termPermissions) {
                if (cloudCodeHelp.isCloudCodeAlias(termPojo.getAlias())) {
                    if (dynamicPermissionSet.contains(termPojo.getAlias())) {
                        termPojo.setValue(1);
                    }
                    continue;
                }
                if (permissionIdsSet.contains(termPojo.getProPermissionId())) {
                    termPojo.setValue(1);
                }
            }
        }

        String dataPermissionDetailStr = role.getDataPermissionDetail();
        List<DataPermissionDetailPojo> dataPermissionDetailPojos = JSON.parseArray(dataPermissionDetailStr, DataPermissionDetailPojo.class);
        if (dataPermissionDetailPojos == null) {
            dataPermissionDetailPojos = new ArrayList<>();
            dataPermission = role.getDataPermission();
        }
        for (DataPermissionDetailPojo pojo : dataPermissionDetailPojos) {
            if (Objects.equals(pojo.getId(), proPermission.getParentId().longValue()) && Objects.equals(pojo.getSaasMark(), SaasMarkEnum.SAAS.getCode())) {
                List<DataPermissionsPojo> permissions = pojo.getPermissions();
                for (DataPermissionsPojo dataPermissionsPojo : permissions) {
                    if (Objects.equals(dataPermissionsPojo.getId(), proPermission.getId().longValue())) {
                        dataPermission = dataPermissionsPojo.getDataPermission();
                        break;
                    }
                }
                break;
            }
        }

        formRoleDetailVO.setDataPermission(dataPermission);
        formRoleDetailVO.setPermission(termPermissions);
        return formRoleDetailVO;
    }

    /**
     * 格式化paas应用菜单/表单模块权限，从数据库存储格式 ==> List<PermissionComplexTermPojo>
     * @param corpid 公司id
     * @param appId 应用id
     * @param menuId 菜单id
     * @param role 角色实体
     */
    private FormRoleDetailVO formatPaasModulePermission(String corpid, Long appId, Long menuId, RoleEntity role) throws XbbException {
        FormRoleDetailVO formRoleDetailVO = new FormRoleDetailVO();
        Integer dataPermission = DataPermissionEnum.SELF.getCode();
        PaasAppEntity paasAppEntity = paasAppModel.getByKey(appId, corpid);
        if (paasAppEntity == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.APP_NOT_EXIST);
        }
        boolean isSaasApp = false;
        Long saasAppId = 0L;
        if (Objects.equals(paasAppEntity.getSaasMark(), SaasMarkEnum.SAAS.getCode())) {
            isSaasApp = true;
            String alias = paasAppEntity.getAlias();
            ProPermissionAliasEnum proPermissionAliasEnum = null;
            if (Objects.equals(alias, XbbRefTypeEnum.CRM.getAlias())) {
                proPermissionAliasEnum = ProPermissionAliasEnum.CRM;
            } else if (Objects.equals(alias, SystemAppMenuEnum.JXC.getAlias())) {
                proPermissionAliasEnum = ProPermissionAliasEnum.JXC;
            } else if (Objects.equals(alias, SystemAppMenuEnum.PRODUCT.getAlias())) {
                proPermissionAliasEnum = ProPermissionAliasEnum.PRODUCT_MANAGEMENT;
            } else if (Objects.equals(alias, SystemAppMenuEnum.FUND_MANAGEMENT.getAlias())) {
                proPermissionAliasEnum = ProPermissionAliasEnum.FUND_MANAGEMENT;
            } else if (Objects.equals(alias, SystemAppMenuEnum.ORDER_CENTER.getAlias())) {
                proPermissionAliasEnum = ProPermissionAliasEnum.ORDER_CENTER;
            } else if (Objects.equals(alias, SystemAppMenuEnum.MARKETING_MANAGEMENT.getAlias())) {
                proPermissionAliasEnum = ProPermissionAliasEnum.MARKETING_MANAGEMENT;
            } else if (Objects.equals(alias, SystemAppMenuEnum.DISTRIBUTOR.getAlias())) {
                proPermissionAliasEnum = ProPermissionAliasEnum.DISTRIBUTOR_MANAGEMENT;
            } else if (Objects.equals(alias, SystemAppMenuEnum.MARKET_MANAGEMENT.getAlias())) {
                proPermissionAliasEnum = ProPermissionAliasEnum.MARKET_MANAGEMENT;
            } else if (Objects.equals(alias, SystemAppMenuEnum.WORK_ORDER_V2_CENTER.getAlias())) {
                proPermissionAliasEnum = ProPermissionAliasEnum.WORK_ORDER_V2_CENTER;
            }
            ProPermissionEntity proPermissionEntity = proPermissionModel.getByAlias(proPermissionAliasEnum.getAlias());
            saasAppId = Long.valueOf(proPermissionEntity.getId());

        }
        PaasMenuEntity paasMenu = paasMenuModel.getByKey(menuId, corpid);
        if (paasMenu == null || !paasMenu.getAppId().equals(appId)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.MENU_NOT_EXIST);
        }

        // 解析appPermissionPojo
        List<PermissionComplexTermPojo> termPermissions = PermissionHelp.initDefaultPaasModulePermission();
        cloudCodeHelp.addCloudCodePermission(corpid, appId, menuId, termPermissions);
        Set<String> dynamicPermissionSet = cloudCodeHelp.getDynamicPermissionSet(role.getDynamicPermissions());
        if (role.isAdminOrBoss()) {
            // 超级管理员和老板有全部paas权限
            for (PermissionComplexTermPojo termPojo : termPermissions) {
                termPojo.setValue(1);
            }
        } else {
            // 其他角色需要进行判断是否具有该paas模块权限
            List<AppPermissionPojo> appPermissions = JSON.parseArray(role.getPaasPermissions(), AppPermissionPojo.class);
            if (appPermissions != null && appPermissions.size() > 0) {
                for (AppPermissionPojo appPermission : appPermissions) {
                    if (appId.equals(appPermission.getAppId())) {
                        List<ModulePermissionPojo> formsPermission = appPermission.getModules();
                        if (formsPermission != null && formsPermission.size() > 0) {
                            for (ModulePermissionPojo module : formsPermission) {
                                if (menuId.equals(module.getId())) {
                                    PermissionTermsPojo enableModulePerms = module.getPermission();
                                    for (PermissionComplexTermPojo termPojo : termPermissions) {
                                        if (cloudCodeHelp.isCloudCodeAlias(termPojo.getAlias())) {
                                            if (dynamicPermissionSet.contains(termPojo.getAlias())) {
                                                termPojo.setValue(1);
                                            }
                                            continue;
                                        }
                                        if (ReflectHelper.valueGet(enableModulePerms, termPojo.getAlias()).equals(1)) {
                                            termPojo.setValue(1);
                                        }
                                    }
                                    break;
                                }
                            }
                        }
                        break;
                    }
                }
            }
        }

        String dataPermissionDetailStr = role.getDataPermissionDetail();
        List<DataPermissionDetailPojo> dataPermissionDetailPojos = JSON.parseArray(dataPermissionDetailStr, DataPermissionDetailPojo.class);
        if (Objects.isNull(dataPermissionDetailPojos)) {
            dataPermissionDetailPojos = new ArrayList<>();
        }

        Map<Long, Integer> idAndDataPermissionMap = new HashMap<>();
        for (DataPermissionDetailPojo pojo : dataPermissionDetailPojos) {
            if (isSaasApp) {
                // saas应用内paas表单
                if (Objects.equals(saasAppId, pojo.getId()) && Objects.equals(SaasMarkEnum.SAAS.getCode(), pojo.getSaasMark())) {
                    List<DataPermissionsPojo> permissions = pojo.getPermissions();
                    for (DataPermissionsPojo dataPermissionsPojo : permissions) {
                        idAndDataPermissionMap.put(dataPermissionsPojo.getId(), dataPermissionsPojo.getDataPermission());
                    }
                }
            } else {
                if (Objects.equals(appId, pojo.getId()) && Objects.equals(SaasMarkEnum.PAAS.getCode(), pojo.getSaasMark())) {
                    List<DataPermissionsPojo> permissions = pojo.getPermissions();
                    for (DataPermissionsPojo dataPermissionsPojo : permissions) {
                        idAndDataPermissionMap.put(dataPermissionsPojo.getId(), dataPermissionsPojo.getDataPermission());
                    }
                }
            }
        }

        if (idAndDataPermissionMap.containsKey(menuId)) {
            dataPermission = idAndDataPermissionMap.get(menuId);
        } else {
            dataPermission = role.getDataPermission();
        }

        formRoleDetailVO.setDataPermission(dataPermission);
        formRoleDetailVO.setPermission(termPermissions);
        return formRoleDetailVO;
    }

    /**
     * saas表单设置中表单权限保存
     * @param businessType saas表单业务类型
     * @param role 角色实体
     * @param termPermissions 表单业务对应的权限
     * @param dataPermission
     * @throws XbbException 业务异常
     */
    private void saasPermissionSave(Integer businessType, RoleEntity role, List<PermissionComplexTermPojo> termPermissions, Integer dataPermission) throws XbbException {
        if (businessType == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002, MessageConstant.ABNORMAL_PARAMETER, "businessType");
        }
        // 通过businessType 获取 alias 和 proPermissionId
        String businessAlias = XbbRefTypeEnum.getByCode(businessType).getAlias();
        ProPermissionEntity proPermission = proPermissionModel.getByAlias(businessAlias);
        if (proPermission == null) {
            return;
        }
        // 已设置的saas权限列表 A集合
        Set<Integer> saasPermissionIdsSet = role.getPermissionIdsSet();
        // 该saas应用对应的权限列表 B集合
        Map<String, Object> params = new HashMap<>(16);
        params.put("parentId", proPermission.getId());
        params.put("del", 0);
        List<Integer> modulePermissionIds = proPermissionModel.findEntityIds(params);

        // 格式化当前保存传过来的该菜单/表单权限列表，C集合
        Set<Integer> submitPermissionIds = new HashSet<>();
        if (termPermissions != null) {
            for (PermissionComplexTermPojo termPojo : termPermissions) {
                if (!cloudCodeHelp.isCloudCodeAlias(termPojo.getAlias()) && termPojo.getValue().equals(1)) {
                    submitPermissionIds.add(termPojo.getProPermissionId());
                }
            }
        }

        // A - B
        saasPermissionIdsSet.removeAll(modulePermissionIds);
        // (A -B) + C
        saasPermissionIdsSet.addAll(submitPermissionIds);
        // 转化为字符串格式 |1|2|3|4|（用“|”分隔）
        String saasPermissionStr = StringUtil.arrayToString(saasPermissionIdsSet.toArray(), "|");
        role.setPermissions(saasPermissionStr);


        String dataPermissionDetailStr = role.getDataPermissionDetail();
        List<DataPermissionDetailPojo> dataPermissionDetailPojos = JSON.parseArray(dataPermissionDetailStr, DataPermissionDetailPojo.class);
        if (dataPermissionDetailPojos == null) {
            dataPermissionDetailPojos = new ArrayList<>();
        }
        boolean isNew = true;
        for (DataPermissionDetailPojo pojo : dataPermissionDetailPojos) {
            if (Objects.equals(pojo.getId(), proPermission.getParentId().longValue()) && Objects.equals(SaasMarkEnum.SAAS.getCode(), pojo.getSaasMark())) {
                List<DataPermissionsPojo> permissions = pojo.getPermissions();
                for (DataPermissionsPojo dataPermissionsPojo : permissions) {
                    if (Objects.equals(dataPermissionsPojo.getId(), proPermission.getId().longValue())) {
                        dataPermissionsPojo.setDataPermission(dataPermission);
                        isNew = false;
                        break;
                    }
                }
                break;
            }
        }
        if (isNew) {
            DataPermissionsPojo dataPermissionsPojo = new DataPermissionsPojo();
            dataPermissionsPojo.setId(proPermission.getId().longValue());
            dataPermissionsPojo.setDataPermission(dataPermission);
            dataPermissionsPojo.setSaasMark(SaasMarkEnum.SAAS.getCode());
            // 是否新增成功
            boolean isAdd = false;
            for (DataPermissionDetailPojo pojo : dataPermissionDetailPojos) {
                if (Objects.equals(pojo.getId(), proPermission.getParentId().longValue()) && Objects.equals(SaasMarkEnum.SAAS.getCode(), pojo.getSaasMark())) {
                    List<DataPermissionsPojo> permissions = pojo.getPermissions();
                    permissions.add(dataPermissionsPojo);
                    isAdd = true;
                    break;
                }
            }
            if (!isAdd) {
                DataPermissionDetailPojo dataPermissionDetailPojo = new DataPermissionDetailPojo();
                dataPermissionDetailPojo.setId(proPermission.getParentId().longValue());
                dataPermissionDetailPojo.setSaasMark(SaasMarkEnum.SAAS.getCode());
                dataPermissionDetailPojo.setPermissions(Collections.singletonList(dataPermissionsPojo));
                dataPermissionDetailPojos.add(dataPermissionDetailPojo);
            }
        }
        role.setDataPermissionDetail(JSON.toJSONString(dataPermissionDetailPojos));

    }

    /**
     * paas表单设置中表单权限保存
     * @param appId 应用id
     * @param menuId 菜单id
     * @param role 角色实体
     * @param termPermissions 应用菜单/表单对应权限
     * @param dataPermission 数据权限
     * @param corpid
     */
    private void paasPermissionSave(Long appId, Long menuId, RoleEntity role, List<PermissionComplexTermPojo> termPermissions, Integer dataPermission, String corpid) throws XbbException {
        // 解析appPermissionPojo
        List<AppPermissionPojo> appPermissions = JSON.parseArray(role.getPaasPermissions(), AppPermissionPojo.class);
        // 为空时候的初始化
        if (appPermissions == null) {
            appPermissions = new ArrayList<>();
        }
        //在paasPermission中找到对应的app权限
        AppPermissionPojo thatAppPerms = null;
        //在paasPermission中找到对应的模块/表单权限
        ModulePermissionPojo thatModulePerms = null;
        for (AppPermissionPojo appPermission : appPermissions) {
            if (appId.equals(appPermission.getAppId())) {
                thatAppPerms = appPermission;
                List<ModulePermissionPojo> formsPermission = appPermission.getModules();
                if (formsPermission != null && formsPermission.size() > 0) {
                    for (ModulePermissionPojo module : formsPermission) {
                        if (menuId.equals(module.getId())) {
                            thatModulePerms = module;
                            break;
                        }
                    }
                }
                break;
            }
        }

        if (thatAppPerms == null) {
            thatAppPerms = new AppPermissionPojo();
            thatAppPerms.setAppId(appId);

            List<ModulePermissionPojo>  modules = new ArrayList<>();
            thatModulePerms = new ModulePermissionPojo();
            thatModulePerms.setId(menuId);
            // TODO 加报表统计后这里注意修改
            thatModulePerms.setType(ModuleTypeEnum.FORM.getCode());
            thatModulePerms.setPermission(convertPaasPermissionFormat(termPermissions));
            modules.add(thatModulePerms);

            thatAppPerms.setModules(modules);
            appPermissions.add(thatAppPerms);
        } else if (thatModulePerms == null) {
            thatModulePerms = new ModulePermissionPojo();
            thatModulePerms.setId(menuId);
            // TODO 加报表统计后这里注意修改
            thatModulePerms.setType(ModuleTypeEnum.FORM.getCode());
            thatModulePerms.setPermission(convertPaasPermissionFormat(termPermissions));

            List<ModulePermissionPojo> modules = thatAppPerms.getModules();
            if (modules == null) {
                modules = new ArrayList<>();
            }
            modules.add(thatModulePerms);
            thatAppPerms.setModules(modules);
        } else {
            thatModulePerms.setPermission(convertPaasPermissionFormat(termPermissions));
        }

        role.setPaasPermissions(JSON.toJSONString(appPermissions));


        PaasAppEntity appEntity = paasAppModel.getByKey(appId, corpid);
        if (Objects.isNull(appEntity)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.APP_NOT_EXIST);
        }
        Integer saasMark = appEntity.getSaasMark();


        String dataPermissionDetailStr = role.getDataPermissionDetail();
        List<DataPermissionDetailPojo> dataPermissionDetailPojos = JSON.parseArray(dataPermissionDetailStr, DataPermissionDetailPojo.class);
        if (Objects.isNull(dataPermissionDetailPojos)) {
            dataPermissionDetailPojos = new ArrayList<>();
        }

        boolean isNew = true;
        if (Objects.equals(saasMark, SaasMarkEnum.SAAS.getCode())) {
            SystemAppMenuEnum byAlias = SystemAppMenuEnum.getSystemAppMenuEnum(appEntity.getAlias());
            ProPermissionAliasEnum proPermissionAliasEnum = null;
            switch (byAlias) {
                case CRM:
                    proPermissionAliasEnum = ProPermissionAliasEnum.CRM;
                    break;
                case PRODUCT:
                    proPermissionAliasEnum = ProPermissionAliasEnum.PRODUCT_MANAGEMENT;
                    break;
                case JXC:
                    proPermissionAliasEnum = ProPermissionAliasEnum.JXC;
                    break;
                case FUND_MANAGEMENT:
                    proPermissionAliasEnum = ProPermissionAliasEnum.FUND_MANAGEMENT;
                    break;
                case WORK_ORDER:
                    proPermissionAliasEnum = ProPermissionAliasEnum.WORK_ORDER_APP;
                    break;
                case CALL_CENTER:
                    break;
                case CALL_CENTER_DU_YAN:
                    break;
                case GROUP_MESSAGE:
                    break;
                case SEARCH_CUSTOMER:
                    break;
                case EXPENSE_MANAGEMENT:
                    break;
            }
            if (Objects.isNull(proPermissionAliasEnum)) {
                return;
            }
            ProPermissionEntity proPermission = proPermissionModel.getByAlias(proPermissionAliasEnum.getAlias());
            if (proPermission == null) {
                return;
            }

            for (DataPermissionDetailPojo pojo : dataPermissionDetailPojos) {
                if (Objects.equals(pojo.getId(), proPermission.getId().longValue()) && Objects.equals(SaasMarkEnum.SAAS.getCode(), pojo.getSaasMark())) {
                    List<DataPermissionsPojo> permissions = pojo.getPermissions();
                    for (DataPermissionsPojo dataPermissionsPojo : permissions) {
                        if (Objects.equals(menuId, dataPermissionsPojo.getId())) {
                            dataPermissionsPojo.setDataPermission(dataPermission);
                            isNew = false;
                            break;
                        }
                    }
                    break;
                }
            }
            if (isNew) {
                DataPermissionsPojo dataPermissionsPojo = new DataPermissionsPojo();
                dataPermissionsPojo.setId(menuId);
                dataPermissionsPojo.setDataPermission(dataPermission);
                dataPermissionsPojo.setSaasMark(SaasMarkEnum.PAAS.getCode());
                boolean noId= true;
                for (DataPermissionDetailPojo pojo : dataPermissionDetailPojos) {
                    if (Objects.equals(pojo.getId(), proPermission.getId().longValue()) && Objects.equals(SaasMarkEnum.SAAS.getCode(), pojo.getSaasMark())) {
                        noId = false;
                        pojo.getPermissions().add(dataPermissionsPojo);
                        break;
                    }
                }
                if (noId) {
                    DataPermissionDetailPojo dataPermissionDetailPojo = new DataPermissionDetailPojo();
                    dataPermissionDetailPojo.setId(proPermission.getId().longValue());
                    dataPermissionDetailPojo.setSaasMark(SaasMarkEnum.SAAS.getCode());
                    dataPermissionDetailPojo.setPermissions(Collections.singletonList(dataPermissionsPojo));
                    dataPermissionDetailPojos.add(dataPermissionDetailPojo);
                }
            }
        } else {
            for (DataPermissionDetailPojo pojo : dataPermissionDetailPojos) {
                if (Objects.equals(pojo.getId(), appId) && Objects.equals(SaasMarkEnum.PAAS.getCode(), pojo.getSaasMark())) {
                    List<DataPermissionsPojo> permissions = pojo.getPermissions();
                    for (DataPermissionsPojo dataPermissionsPojo : permissions) {
                        if (Objects.equals(menuId, dataPermissionsPojo.getId())) {
                            dataPermissionsPojo.setDataPermission(dataPermission);
                            isNew = false;
                            break;
                        }
                    }
                    break;
                }
            }
            if (isNew) {
                DataPermissionsPojo dataPermissionsPojo = new DataPermissionsPojo();
                dataPermissionsPojo.setId(menuId);
                dataPermissionsPojo.setDataPermission(dataPermission);
                dataPermissionsPojo.setSaasMark(SaasMarkEnum.PAAS.getCode());
                boolean noId = true;
                for (DataPermissionDetailPojo pojo : dataPermissionDetailPojos) {
                    if (Objects.equals(pojo.getId(), appId) && Objects.equals(SaasMarkEnum.PAAS.getCode(), pojo.getSaasMark())) {
                        noId = false;
                        pojo.getPermissions().add(dataPermissionsPojo);
                        break;
                    }
                }
                if (noId) {
                    DataPermissionDetailPojo dataPermissionDetailPojo = new DataPermissionDetailPojo();
                    dataPermissionDetailPojo.setId(appId);
                    dataPermissionDetailPojo.setSaasMark(SaasMarkEnum.PAAS.getCode());
                    dataPermissionDetailPojo.setPermissions(Collections.singletonList(dataPermissionsPojo));
                    dataPermissionDetailPojos.add(dataPermissionDetailPojo);
                }
            }
        }


        role.setDataPermissionDetail(JSON.toJSONString(dataPermissionDetailPojos));
    }

    /**
     * 转换 List<PermissionComplexTermPojo> ==> PermissionTermsPojo
     * @param termPermissions 前端格式
     * @return paas存储格式
     */
    private PermissionTermsPojo convertPaasPermissionFormat(List<PermissionComplexTermPojo> termPermissions) {
        // 转换 List<PermissionComplexTermPojo> ==> PermissionTermsPojo
        PermissionTermsPojo termsPojo = new PermissionTermsPojo();
        if (termPermissions != null && termPermissions.size() > 0) {
            for (PermissionComplexTermPojo complexTermPojo : termPermissions) {
                if (complexTermPojo.getValue().equals(1)) {
                    ReflectHelper.valueSet(termsPojo, complexTermPojo.getAlias(), 1);
                }
            }
        }
        return termsPojo;
    }

    @Override
    public List<PaasFormEntityExt> getEnableCustomerFormList(UserVO loginUser) {
        Integer businessType = XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode();
        List<PaasFormEntityExt> paasFormEntityExtList = paasFormModel.getEnableFormList(loginUser.getCorpid(), businessType);
        removeByPermission(paasFormEntityExtList, loginUser);
        return paasFormEntityExtList;
    }

    @Override
    public List<PaasFormEntityExt> getEnableCustomerFormListDistributor(UserVO loginUser, Integer distributorMark) {
        Integer businessType = XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode();
        List<PaasFormEntityExt> paasFormEntityExtList = paasFormModel.getEnableFormListDistributor(loginUser.getCorpid(), businessType, distributorMark);
        removeByPermission(paasFormEntityExtList, loginUser);
        return paasFormEntityExtList;
    }

    @Override
    public List<PaasFormEntityExt> getEnableContractFormList(UserVO loginUser) {
        Integer businessType = XbbRefTypeEnum.CONTRACT.getCode();
        List<PaasFormEntityExt> paasFormEntityExtList = paasFormModel.getEnableFormList(loginUser.getCorpid(), businessType);
        removeByPermission(paasFormEntityExtList, loginUser);
        return paasFormEntityExtList;
    }

    @Override
    public List<PaasFormEntityExt> getEnableContractFormListDistributor(UserVO loginUser, Integer distributorMark) {
        Integer businessType = XbbRefTypeEnum.CONTRACT.getCode();
        List<PaasFormEntityExt> paasFormEntityExtList = paasFormModel.getEnableFormListDistributor(loginUser.getCorpid(), businessType,distributorMark);
        removeByPermission(paasFormEntityExtList, loginUser);
        return paasFormEntityExtList;
    }

    @Override
    public List<PaasFormEntityExt> getEnableClueFormList(UserVO loginUser) {
        Integer businessType = XbbRefTypeEnum.CLUE.getCode();
        List<PaasFormEntityExt> paasFormEntityExtList = paasFormModel.getEnableFormList(loginUser.getCorpid(), businessType);
        removeByPermission(paasFormEntityExtList, loginUser);
        return paasFormEntityExtList;
    }

    @Override
    public List<PaasFormEntityExt> getEnableContactFormList(UserVO loginUser) {
        Integer businessType = XbbRefTypeEnum.CONTACT.getCode();
        List<PaasFormEntityExt> paasFormEntityExtList = paasFormModel.getEnableFormList(loginUser.getCorpid(), businessType);
        removeByPermission(paasFormEntityExtList, loginUser);
        return paasFormEntityExtList;
    }

    @Override
    public void removeByPermission(List<PaasFormEntityExt> paasFormEntityList, UserVO loginUser) {
       paasFormModel.removeByPermission(paasFormEntityList, loginUser);
    }

    /**
     * 业务规则-校验版本以及白名单
     * @param businessRuleWhiteDTO
     * @return
     * @throws
     * @author xingxing.xiao
     * @date 2020/05/11 17:07
     */
    @Override
    public BusinessRuleWhiteVO validateVersionAndWhite(BusinessRuleWhiteDTO businessRuleWhiteDTO) throws XbbException {
        BusinessRuleWhiteVO businessRuleWhiteVO = new BusinessRuleWhiteVO();
        String corpid = businessRuleWhiteDTO.getCorpid();
        try {
            Integer feeType = businessRuleUserPermissionHelp.getFeeType(corpid);
            businessRuleWhiteVO.setFeeType(feeType);
        } catch (XbbException e){
            throw e;
        } catch (Exception e){
            LOG.error("业务规则-校验版本以及白名单出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return businessRuleWhiteVO;
    }

    @Override
    public EnableAssociationListVO enableAssociation(EnableAssociationListDTO enableAssociationListDTO) throws XbbException {
        EnableAssociationListVO enableAssociationListVO = new EnableAssociationListVO();
        try {
            String corpid = enableAssociationListDTO.getCorpid();
            PaasFormEntity paasFormEntity = new PaasFormEntity();
            if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), enableAssociationListDTO.getBusinessType())) {
                WorkOrderFormEntity workOrderFormEntity = workOrderFormModel.getByKey(enableAssociationListDTO.getFormId(), corpid);
                if (Objects.isNull(workOrderFormEntity)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
                }
                BeanUtil.copyProperties(workOrderFormEntity, paasFormEntity);
            } else {
                paasFormEntity = paasFormModel.getByKey(enableAssociationListDTO.getFormId(), corpid);

            }
            if (Objects.isNull(paasFormEntity)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
            }
            List<LinkListPojo> associationList = enableAssociationListDTO.getAssociationList();
            int num = getAssociationListMaxNum(corpid);
            if (associationList.size() > num) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, String.format(I18nMessageUtil.getMessage(MessageConstant.ASSOCIATION_LIST_MAX_SIZE), num));
            }
            if (CollectionsUtil.isNotEmpty(associationList)) {
                associationList.forEach(item->{
                    if (item.getAttr().contains(".")) {
                        String[] list = item.getAttr().split("\\.");
                        if (list.length == BasicConstant.THREE) {
                            item.setAttr(list[0] + StringConstant.POINT + list[2]);
                        }
                    }
                });
            }

            if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), enableAssociationListDTO.getBusinessType())) {
                WorkOrderFormEntity entity = new WorkOrderFormEntity();
                entity.setCorpid(corpid);
                entity.setId(paasFormEntity.getId());
                entity.setAssociationList(JSON.toJSONString(associationList));
                entity.setUpdateTime((long)DateUtil.getInt());
                workOrderFormModel.update(entity);
            } else {
                PaasFormEntity entity = new PaasFormEntity();
                entity.setCorpid(corpid);
                entity.setId(paasFormEntity.getId());
                entity.setAssociationList(JSON.toJSONString(associationList));
                entity.setUpdateTime((long)DateUtil.getInt());
                paasFormModel.update(entity);
            }

        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("PaasFormServiceImpl.enableAssociation  出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return enableAssociationListVO;
    }

    @Override
    public BaseVO enableChangeTime(RuleEnableDTO ruleEnableDTO) throws XbbException{
        BaseVO baseVO = new BaseVO();
        try {
            List<RuleEnablePojo> paramList = new ArrayList<>(8);
            paramList.addAll(ruleEnableDTO.getAssociatedBusinessList());
            paramList.addAll(ruleEnableDTO.getCallLogList());
            paramList.addAll(ruleEnableDTO.getCustomerStageList());
            String corpid = ruleEnableDTO.getCorpid();
            List<String> configList = new ArrayList<>();
            for (RuleEnablePojo ruleEnablePojo : paramList) {
                configList.add(ruleEnablePojo.getConfig());
            }
            if (configList.isEmpty()) {
                return new BaseVO();
            }
            List<FormConfigEntity> configEntityList = formConfigModel.getButtonEntityByFormId(corpid, ruleEnableDTO.getFormId(), configList);
            Map<String, FormConfigEntity> formConfigEntityMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (FormConfigEntity formConfigEntity : configEntityList) {
                formConfigEntityMap.put(formConfigEntity.getConfig(), formConfigEntity);
            }
            List<FormConfigEntity> formConfigEntityList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            FormConfigEntity configEntity = null;
            for (RuleEnablePojo ruleEnablePojo : paramList) {
                configEntity = formConfigEntityMap.get(ruleEnablePojo.getConfig());
                if (Objects.isNull(configEntity)) {
                    configEntity = new FormConfigEntity();
                    configEntity.setConfig(ruleEnablePojo.getConfig());
                    configEntity.setConfigValue(ruleEnablePojo.getConfigValue());
                    configEntity.setCorpid(ruleEnableDTO.getCorpid());
                    configEntity.setFormId(ruleEnableDTO.getFormId());
                    formConfigEntityList.add(configEntity);
                }
            }

            if (CollectionsUtil.isNotEmpty(formConfigEntityList)) {
                formConfigModel.insertBatch(formConfigEntityList);
                List<RuleEnablePojo> customerStageList = ruleEnableDTO.getCustomerStageList();
                List<FormConfigEntity> list = customerStageList.stream().filter(ruleEnablePojo -> "1".equals(ruleEnablePojo.getConfigValue())).map(ruleEnablePojo -> {
                    FormConfigEntity formConfigEntity = new FormConfigEntity();
                    BeanUtil.copyProperties(ruleEnablePojo, formConfigEntity);
                    return formConfigEntity;
                }).collect(Collectors.toList());
                if (CollectionsUtil.isNotEmpty(list)) {
                    formConfigModel.updateBatch(list, corpid);
                }
            } else {
                List<FormConfigEntity> updateList = new ArrayList<>();
                for (RuleEnablePojo ruleEnablePojo : paramList) {
                    FormConfigEntity formConfigEntity = new FormConfigEntity();
                    formConfigEntity.setId(ruleEnablePojo.getId());
                    formConfigEntity.setConfig(ruleEnablePojo.getConfig());
                    formConfigEntity.setConfigValue(ruleEnablePojo.getConfigValue());
                    updateList.add(formConfigEntity);
                }
                formConfigModel.updateBatch(updateList, corpid);
            }
        } catch (Exception e) {
            LOG.error("PaasFormServiceImpl.enableChangeTime", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return baseVO;
    }

    @Override
    public FormAssociationListVO associationList(FormAssociationListDTO formAssociationListDTO) throws XbbException {
        FormAssociationListVO formAssociationListVO = new FormAssociationListVO();
        try {
            String corpid = formAssociationListDTO.getCorpid();
            Integer businessType = formAssociationListDTO.getBusinessType();
            Long formId = formAssociationListDTO.getFormId();
            PaasFormEntity paasFormEntity = proFormHelp.getPaasForm(formId, businessType, corpid);

            List<LinkListPojo> associationList = JSONArray.parseArray(paasFormEntity.getAssociationList(), LinkListPojo.class);
            if (Objects.isNull(associationList)) {
                associationList = new ArrayList<>();
            }
            List<LinkListPojo> enableAssociationList = new ArrayList<>();
            Set<Long> appIdIn = new HashSet<>();
            Set<Long> menuIdIn = new HashSet<>();
            associationList.forEach(item->{
                appIdIn.add(item.getLinkAppId());
                if (Objects.nonNull(item.getLinkMenuId())) {
                    menuIdIn.add(item.getLinkMenuId());
                }
            });
            // 获取已开启的应用
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("del", DelEnum.NORMAL.getDel());
            param.put("enable", 1);
            param.put("idIn", appIdIn);
            List<PaasAppEntity> appList = paasAppModel.findEntitys(param);
            if (Objects.isNull(appList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
            Map<Long, PaasAppEntity> appMap = new HashMap<>(appList.size());
            appList.forEach(item->{
                appMap.put(item.getId(), item);
            });
            // 获取已开启的菜单
            param.clear();
            param.put("corpid", corpid);
            param.put("del", DelEnum.NORMAL.getDel());
            param.put("enable", 1);
            param.put("idIn", menuIdIn);
            List<PaasMenuEntity> menuList = paasMenuModel.findEntitys(param);
            if (Objects.isNull(menuList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
            Map<Long, PaasMenuEntity> menuMap = new HashMap<>(menuList.size());
            menuList.forEach(item->{
                menuMap.put(item.getId(), item);
            });
            List<Long> formIdList = new ArrayList<>();
            List<Long> workOrderFormIdList = new ArrayList<>();
            for (LinkListPojo item : associationList) {
                if (appMap.isEmpty() || menuMap.isEmpty()) {
                    continue;
                }
                // 开启了应用和菜单才需要显示
                if (appMap.containsKey(item.getLinkAppId()) && menuMap.containsKey(item.getLinkMenuId())) {
                    if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), item.getLinkBusinessType())) {
                        workOrderFormIdList.add(item.getLinkFormId());
                    } else {
                        formIdList.add(item.getLinkFormId());
                    }
                }
            }
            Map<Long, PaasFormEntityExt> formMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<Long, WorkOrderFormEntity> workOrderFormMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            if (!formIdList.isEmpty()) {
                param.clear();
                param.put(StringConstant.CORPID, corpid);
                param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                param.put("idIn", formIdList);
                param.put("enable", 1);
                List<PaasFormEntityExt> paasFormList = paasFormModel.list(param);
                //todo: 如果上面的 param 以后加入了 sort值排序，那么执行完上面的查询以后，记得要 params.remove("orderByStrGroup");，因为params后面被复用了
                if (Objects.isNull(paasFormList)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
                }

                paasFormList.forEach(item->{
                    formMap.put(item.getId(), item);
                });
            }
            if (!workOrderFormIdList.isEmpty()) {
                param.clear();
                param.put(StringConstant.CORPID, corpid);
                param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                param.put("idIn", workOrderFormIdList);
                param.put("enable", 1);
                List<WorkOrderFormEntity> workOrderFormList = workOrderFormModel.findEntitys(param);
                if (Objects.isNull(workOrderFormList)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
                }

                workOrderFormList.forEach(item->{
                    workOrderFormMap.put(item.getId(), item);
                });
            }
            Iterator<LinkListPojo> iterator = associationList.iterator();
            while (iterator.hasNext()) {
                LinkListPojo item = iterator.next();
                if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), item.getLinkBusinessType())) {
                    if (Objects.isNull(workOrderFormMap.get(item.getLinkFormId()))) {
                        iterator.remove();
                        continue;
                    }
                    WorkOrderFormEntity workOrderFormEntity = workOrderFormMap.get(item.getLinkFormId());
                    item.setName(workOrderFormEntity.getName());
                    if (Objects.equals(item.getEnable(), 1)) {
                        enableAssociationList.add(item);
                        iterator.remove();
                        continue;
                    }
                } else {
                    if (Objects.isNull(formMap.get(item.getLinkFormId()))) {
                        iterator.remove();
                        continue;
                    }
                    PaasFormEntityExt paasFormEntityExt = formMap.get(item.getLinkFormId());
                    item.setName(paasFormEntityExt.getName());
                    item.setLinkBusinessType(paasFormEntityExt.getBusinessType());
                    if (Objects.equals(item.getEnable(), 1)) {
                        enableAssociationList.add(item);
                        iterator.remove();
                        continue;
                    }
                }
            }
            Integer num = getAssociationListMaxNum(corpid);
            formAssociationListVO.setNum(num);
            formAssociationListVO.setAssociationList(associationList);
            formAssociationListVO.setEnableAssociationList(enableAssociationList);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("PaasFormServiceImpl.associationList  出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return formAssociationListVO;
    }

    /**
     * 获取关联列表表单最大值
     * @param corpid
     * @return
     */
    private Integer getAssociationListMaxNum(String corpid) {

        String value = paasRedisHelper.getValue(CompanyConfigEnum.ASSOCIATION_LIST.getAlias(), corpid);
        if (StringUtil.isEmpty(value)) {
            Integer num = PaasConstant.ASSOCIATION_LIST_MAX_SIZE;
            CompanyConfigEntity companyConfigEntity = companyConfigModel.getByConfigAlias(CompanyConfigEnum.ASSOCIATION_LIST.getAlias(), corpid);
            if (Objects.nonNull(companyConfigEntity)) {
                num = Integer.valueOf(companyConfigEntity.getConfigValue());
            }
            paasRedisHelper.setValue(CompanyConfigEnum.ASSOCIATION_LIST.getAlias(), corpid, num, RedisTimeConstant.TEN_MINUTES);
            return num;
        }
        return Integer.valueOf(value);
    }

    @Override
    public Long getFormIdByBusinessType(String corpid, int businessType) {
        if (Objects.equals(businessType, XbbRefTypeEnum.PRODUCT.getCode())) {
            String value = paasRedisHelper.getValue(RedisPrefixConstant.PRODUCT_FORM_ID, corpid);
            Long formId;
            if (Objects.isNull(value)) {
                formId = paasFormModel.getFormIdByBusinessType(corpid, businessType);
                paasRedisHelper.setValue(RedisPrefixConstant.PRODUCT_FORM_ID, corpid, formId, RedisTimeConstant.HUGE_DURATION);
            } else {
                formId = Long.valueOf(value);
            }
            return formId;
        } else {
            return paasFormModel.getFormIdByBusinessType(corpid,businessType);
        }
    }

    @Override
    public HomePageListVO homePageList(BaseDTO baseDTO) throws XbbException {
        HomePageListVO homePageListVO = new HomePageListVO();
        String corpid = baseDTO.getCorpid();
        String userId = baseDTO.getUserId();
        List<HomePagePoJo> homePages = new ArrayList<>();
        UserConfigEntity userConfigEntity = userConfigModel.getByUserId(userId, corpid, UserConfigEnum.HOME_MANAGEMENT.getAlias());
        String configValue;
        if (userConfigEntity != null) {
            configValue = userConfigEntity.getConfigValue();
        } else {
            CompanyConfigEntity configEntity = companyConfigModel.getConfigEntity(corpid, UserConfigEnum.HOME_MANAGEMENT.getAlias());
            configValue = configEntity == null ? null : configEntity.getConfigValue();
        }
        List<Long> categoryIds = new ArrayList<>();
        if (StringUtil.isEmpty(configValue)) {
            //兼容没有首页管理公司配置的情况
            HomePagePoJo homePagePoJo = new HomePagePoJo(0L, I18nMessageUtil.getMessage(CommonConstant.CRM_HOME), 0, 1);
            homePages.add(homePagePoJo);
            homePageListVO.setHomePages(homePages);
            // 以下参数就是为了兼容返回的数量显示问题
            homePageListVO.setTotalNum(ChartConstant.PUBLISH_MAX);
            homePageListVO.setUsedNum(BasicConstant.ONE);
            homePageListVO.setCustomTotalNum(ChartConstant.PUBLISH_MAX);
            homePageListVO.setCustomUsedNum(BasicConstant.ZERO);
            return homePageListVO;
        }else {
            JSONArray configValueArr = JSON.parseArray(configValue);
            if (configValueArr != null && configValueArr.size() > 0) {
                homePages = configValueArr.toJavaList(HomePagePoJo.class);
            }
            homePages.forEach(e -> categoryIds.add(e.getId()));
        }
        //国际化处理CRM首页按钮
        if (!CollectionUtils.isEmpty(homePages)){
            for (HomePagePoJo homePagePoJo : homePages){
                if (Objects.equals(homePagePoJo.getId(), 0L)) {
                    homePagePoJo.setName(I18nMessageUtil.getMessage(CommonConstant.CRM_HOME));
                    break;
                }
            }
        }
        Locale locale = LocaleContextHolder.getLocale();
        String lang = locale.toString();
        ChartCategoryListByIdInDTO categoryListByIdInDTO = new ChartCategoryListByIdInDTO();
        BeanUtil.copyProperties(baseDTO, categoryListByIdInDTO);
        categoryListByIdInDTO.setIdIn(categoryIds);
        //获取有权限的分类列表
        XbbResponse<ChartCategoryListByIdInVO> xbbResponse = chartResultFeignClient.chartCategoryListByIdIn(categoryListByIdInDTO, lang);
        ChartCategoryListByIdInVO chartCategoryListByIdInVO = xbbResponse.getResult();
        List<ChartCategoryEntity> list = chartCategoryListByIdInVO.getList();
        Map<Long, ChartCategoryEntity> idInToCategory = list.stream().collect(Collectors.toMap(ChartCategoryEntity::getId, ChartCategoryEntity -> ChartCategoryEntity));
        boolean enFlag = Objects.equals(locale.getLanguage(), I18nStringConstant.ENGLISH_LANGUAGE);
        // 遍历首页管理表，一个公司不会太多，最多50
        List<HomePagePoJo> customHomePageList = new ArrayList<>();
        Boolean isUltimate = Objects.equals(packageHelp.getFeeType(corpid), PackageTypeEnum.ULTIMATE.getType());
        List<Long> customHomePageIdList = new ArrayList<>();
        if (isUltimate){
//            customHomePageIdList = new ArrayList<>();
            Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid",corpid);
            param.put("del",DelEnum.NORMAL.getDel());
            param.put("enable", EnableEnum.OPEN.getCode());
            List<HomePageManageEntity> homePageManageList = homePageManageModel.findEntitys(param);
            HomePageVisibleDTO homePageVisibleDTO = new HomePageVisibleDTO();
            homePageVisibleDTO.setList(homePageManageList);
            homePageVisibleDTO.setLoginUser(baseDTO.getLoginUser());
            HomePageVisibleVO homePageVisibleVO = homePageManageService.homePageListIsVisible(homePageVisibleDTO);
            List<HomePageManageEntity> visibleIdList = homePageVisibleVO.getList();
            if (!CollectionUtils.isEmpty(visibleIdList)){
                visibleIdList.forEach(item ->{
                    HomePagePoJo homePagePoJo = new HomePagePoJo(item.getId(),item.getName(),0,0,1);
                    customHomePageList.add(homePagePoJo);
                    customHomePageIdList.add(item.getId());
                });
                homePageListVO.setShowCustom(BasicConstant.ONE);
            }
        }

        //当前首页被删除或无权限时，数组第一个作为默认首页
        boolean flag = false;
        boolean hasCustomFlag = false;
        Iterator<HomePagePoJo> iterator = homePages.iterator();
        Integer usedNum = 0;
        Integer customUsedNum = 0;
        while(iterator.hasNext()){
            HomePagePoJo e = iterator.next();
            Long id = e.getId();
            // 自定义首页id是默认为0的,有管理员分配的首页，id为0的crm首页得去掉
            if (!CollectionUtils.isEmpty(customHomePageList) && Objects.equals(e.getId(),0L)){
                e.setEnable(EnableEnum.CLOSE.getCode());
                e.setMain(BasicConstant.ZERO);
                if (Objects.equals(e.getEnable(), EnableEnum.OPEN.getCode())){
                    usedNum ++;
                }
//                iterator.remove();
                continue;
            }
            if (CollectionUtils.isEmpty(customHomePageList) && Objects.equals(e.getId(),0L)){
                e.setEnable(EnableEnum.OPEN.getCode());
                usedNum ++;
//                iterator.remove();
                continue;
            }
            if (Objects.equals(e.getIsCustom(),1)){
                if (CollectionUtils.isEmpty(customHomePageIdList)){
                    iterator.remove();
                    continue;
                }
                // 不在适应范围内或者删掉的管理员分配首页给remove掉
                if (!customHomePageIdList.contains(e.getId())){
                    iterator.remove();
                    continue;
                }else {
                    if (!hasCustomFlag){
                        hasCustomFlag = true;
                    }
                    if (Objects.equals(e.getEnable(), EnableEnum.OPEN.getCode())){
                        customUsedNum ++;
                    }
                    customHomePageIdList.remove(e.getId());
                }
            }
            if (Objects.equals(e.getIsCustom(),1)){
                // 至少有一个main为1的首页，没有后面设置第一个为1
                if (Objects.equals(e.getMain(), BasicConstant.ONE)) {
                    if (!flag){
                        flag = true;
                    }
                }
                continue;
            }

            // 仪表盘权限过滤
            if (null == id){
                iterator.remove();
                continue;
            }
            boolean isContains = idInToCategory.containsKey(id);
            if (!isContains && id != 0) {
                iterator.remove();
                continue;
            } else if (isContains){
                //分类名以查询为准
                if (enFlag) {
                    e.setName(idInToCategory.get(id).getNameEn());
                }else {
                    e.setName(idInToCategory.get(id).getName());
                }
                if (Objects.equals(e.getEnable(), EnableEnum.OPEN.getCode())){
                    usedNum ++;
                }
            }
            // 至少有一个main为1的首页，没有后面设置第一个为1
            if (Objects.equals(e.getMain(), BasicConstant.ONE)) {
                if (!flag){
                    flag = true;
                }
            }
        }
        // 加上用户配置表里面没有的自定义首页
        customHomePageList.removeIf(item -> !customHomePageIdList.contains(item.getId()));
        if (!CollectionUtils.isEmpty(customHomePageList)){
            // 原来列表里面没有自定义首页，或者有被删除了，第一个要放自定义首页
            if (!flag && !hasCustomFlag){
                List<HomePagePoJo> tempHomePages = new ArrayList<>();
                tempHomePages.addAll(customHomePageList);
                tempHomePages.addAll(homePages);
                homePages = tempHomePages;
            }else {
                for (HomePagePoJo item : customHomePageList) {
                    if (Objects.equals(item.getEnable(), EnableEnum.OPEN.getCode())) {
                        customUsedNum++;
                    }
                }
                homePages.addAll(customHomePageList);
            }
        }
        if(!flag) {
            for (HomePagePoJo item : homePages) {
                if (Objects.equals(item.getEnable(), BasicConstant.ONE)) {
                    item.setMain(BasicConstant.ONE);
                    break;
                }
            }
        }
        homePageListVO.setHomePages(homePages);
        homePageListVO.setTotalNum(ChartConstant.PUBLISH_MAX);
        homePageListVO.setUsedNum(usedNum);
        homePageListVO.setCustomTotalNum(ChartConstant.PUBLISH_MAX);
        homePageListVO.setCustomUsedNum(customUsedNum);
        return homePageListVO;
    }

    @Override
    public BaseVO homePageUpdate(HomePageUpdateDTO homePageUpdateDTO) throws XbbException {
        List<HomePagePoJo> pagePoJos = homePageUpdateDTO.getHomePages();
        Map<Long, HomePagePoJo> idToHomePage = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, HomePagePoJo> idToHomePageCustom = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (!CollectionUtils.isEmpty(pagePoJos)){
            pagePoJos.forEach(pojo ->{
                if (Objects.equals(pojo.getIsCustom(),BasicConstant.ONE)){
                    idToHomePageCustom.put(pojo.getId(),pojo);
                }else {
                    idToHomePage.put(pojo.getId(),pojo);
                }
            });
        }
        String corpid = homePageUpdateDTO.getCorpid();
        String userId = homePageUpdateDTO.getUserId();
        try {
            //若公司配置信息中存在个人配置没有的仪表盘信息，则同步更新
            CompanyConfigEntity configEntity = companyConfigModel.getConfigEntity(corpid, UserConfigEnum.HOME_MANAGEMENT.getAlias());
            if (configEntity != null) {
                List<HomePagePoJo> configPages = JSON.parseArray(configEntity.getConfigValue(), HomePagePoJo.class);
                for (HomePagePoJo homePagePoJo : configPages) {
                    Long id = homePagePoJo.getId();
                    if (Objects.equals(homePagePoJo.getIsCustom(),BasicConstant.ONE)){
                        if (!idToHomePageCustom.containsKey(id)) {
                            pagePoJos.add(homePagePoJo);
                        }
                        idToHomePageCustom.remove(id);
                    }else {
                        if (!idToHomePage.containsKey(id)) {
                            pagePoJos.add(homePagePoJo);
                        }
                        idToHomePage.remove(id);
                    }
                }
                if (CollectionsUtil.isNotEmpty(idToHomePage.keySet())){
                    pagePoJos.removeAll(idToHomePage.values());
                }
                if (CollectionsUtil.isNotEmpty(idToHomePageCustom.keySet())){
                    pagePoJos.removeAll(idToHomePageCustom.values());
                }
            }
            if (CollectionUtils.isEmpty(pagePoJos)) {
                HomePagePoJo homePagePoJo = new HomePagePoJo(0L, "CRM首页", 0, 1);
                pagePoJos.add(homePagePoJo);
            }
            JSONArray homePageArray = JSON.parseArray(JSON.toJSONString(pagePoJos));
            userConfigModel.save(corpid, userId, UserConfigEnum.HOME_MANAGEMENT.getAlias(), UserConfigEnum.HOME_MANAGEMENT.getName(), homePageArray.toJSONString());
        } catch (Exception e) {
            LOG.error("homePageUpdate save", e);
        }
        return new BaseVO();
    }

    @Override
    public BaseVO homePageDelete(HomePageDeleteDTO homePageDeleteDTO) throws XbbException {
        Long categoryId = homePageDeleteDTO.getCategoryId();
        String corpid = homePageDeleteDTO.getCorpid();
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(StringConstant.CORPID, corpid);
        param.put("configAlias", UserConfigEnum.HOME_MANAGEMENT.getAlias());
        param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        List<UserConfigEntity> userConfigList = userConfigModel.list(param);
        CompanyConfigEntity configEntity = companyConfigModel.getConfigEntity(corpid, UserConfigEnum.HOME_MANAGEMENT.getAlias());
        List<HomePagePoJo> homePages;
        if (configEntity != null) {
            String configValue = configEntity.getConfigValue();
            JSONArray configValueArr = JSON.parseArray(configValue);
            if (configValueArr != null && configValueArr.size() > 0) {
                homePages = configValueArr.toJavaList(HomePagePoJo.class);
                int size = homePages.size();
                homePages.removeIf(e -> Objects.equals(e.getId(), categoryId) && !Objects.equals(e.getIsCustom(),BasicConstant.ONE));
                if (homePages.size() != size) {
                    configValue = JSON.toJSONString(homePages);
                    try {
                        companyConfigModel.save(corpid, UserConfigEnum.HOME_MANAGEMENT.getAlias(), UserConfigEnum.HOME_MANAGEMENT.getName(), configValue);
                    } catch (Exception e) {
                        LOG.error("homePageDelete companyConfigModel.save", e);
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
                    }
                }
            }
        }
        if (CollectionsUtil.isNotEmpty(userConfigList)) {
            List<UserConfigEntity> updateList = new ArrayList<>();
            for (UserConfigEntity userConfigEntity : userConfigList) {
                String configValue = userConfigEntity.getConfigValue();
                JSONArray configValueArr = JSON.parseArray(configValue);
                if (configValueArr != null && configValueArr.size() > 0) {
                    List<HomePagePoJo> userHomePageList = configValueArr.toJavaList(HomePagePoJo.class);
                    int size = userHomePageList.size();
                    userHomePageList.removeIf(e -> Objects.equals(e.getId(), categoryId) && !Objects.equals(e.getIsCustom(),BasicConstant.ONE));
                    if (userHomePageList.size() != size) {
                        userConfigEntity.setConfigValue(JSON.toJSONString(userHomePageList));
                        updateList.add(userConfigEntity);
                    }
                }
            }
            if (updateList.size() > 0) {
                try {
                    userConfigModel.updateBatch(updateList, corpid);
                } catch (Exception e) {
                    LOG.error("homePageDelete userConfigModel.updateBatch", e);
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
                }
            }
        }
        return new BaseVO();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public FormDeleteVO deleteByPackage(FormDeleteDTO formDeleteDTO) throws XbbException {
        FormDeleteVO formDeleteVO = new FormDeleteVO();
        try {
            UserVO userVO = formDeleteDTO.getLoginUser();
            if (!userVO.isAdminOrBoss() && !userVO.getPermSet().contains(ProPermissionAliasEnum.FORM_SET_DELETE.getAlias())) {
                throw new XbbException(ProErrorCodeEnum.API_ERROR_260001 );
            }
            Long formId = formDeleteDTO.getFormId();
            Integer saasMark = formDeleteDTO.getSaasMark();
            if (Objects.equals(saasMark, SaasMarkEnum.SAAS.getCode())) {
                throw new XbbException(ProErrorCodeEnum.API_ERROR_260001 );
            }
            String corpid = formDeleteDTO.getCorpid();

            // 获取表单
            PaasFormEntity paasFormEntity = paasFormModel.getByKey(formDeleteDTO.getFormId(), corpid);
            if (Objects.isNull(paasFormEntity)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
            }
            MenuFormDelDTO menuFormDelDTO = new MenuFormDelDTO();
            BeanUtil.copyProperties(formDeleteDTO, menuFormDelDTO);
            paasMenuService.deleteFormMenu(menuFormDelDTO);
            // 删除表单
            paasFormModel.delete(paasFormEntity.getId(), corpid);

            FormExplainDeleteDTO formExplainDeleteDTO = new FormExplainDeleteDTO();
            BeanUtil.copyProperties(formDeleteDTO, formExplainDeleteDTO);
            paasFormExplainService.delete(formExplainDeleteDTO);

            // 删除表单时，需要判断该表单是否被关联列表设置

            deleteOtherByDeleteForm(formId, corpid, formDeleteDTO.getBusinessType());
            // 删除数据
            Runnable runnable = () -> {
                BoolQueryBuilder boolQueryBuilder = boolQuery();
                SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
                boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
                boolQueryBuilder.filter(termQuery("del", DelEnum.NORMAL.getDel()));
                boolQueryBuilder.filter(termQuery("formId", formDeleteDTO.getFormId()));
                IndexTypeEnum indexTypeEnum = IndexTypeEnum.IDX_FORM_DATA;
                boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, indexTypeEnum.getType()));
                sourceBuilder.query(boolQueryBuilder);
                SearchRequest searchRequest = new SearchRequest(indexTypeEnum.getIndex());
                searchRequest.source(sourceBuilder);
                CountRequest countRequest = new CountRequest(searchRequest.indices()[0]);
                countRequest.query(searchRequest.source().query());
                try {
                    long count = xbbElasticsearchRestTemplate.count(countRequest);
                    if (count > 0) {
                        LOG.info("共：" + count + "条");
                        Integer pageSize = 100;
                        long index = count/pageSize + 1;
                        Long page = 0L;
                        for (int j = 0; j < index; j++) {
                            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                            param.put(StringConstant.CORPID, corpid);
                            param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                            param.put(StringConstant.FORM_ID, formId);
                            param.put("idGte", page);
                            param.put("pageSize", pageSize);
                            param.put("orderByStr", "id ASC");
                            param.put(StringConstant.COLUMNS, "id");
                            List<PaasFormDataEntityExt> formDataList = paasFormDataModel.findEntitys(param);
                            if (CollectionsUtil.isNotEmpty(formDataList)) {
                                Integer total = formDataList.size();
                                page = formDataList.get(total-1).getId();
                                List<Long> idList = new ArrayList<>();
                                formDataList.forEach(item->{
                                    idList.add(item.getId());
                                });
                                paasFormDataModel.deleteBatch(idList, corpid, DelEnum.DELETE.getDel());
                            }
                        }
                    }

                } catch (Exception e) {
                    LOG.error("PaasFormServiceImpl.deleteByPackage  删除数据出错", e);
                }
            };
            threadPoolBeanConfig.deleteFormData().execute(runnable);
            String key = corpid + "_"+ ValueAddedTypeEnum.CUSTOM_FORM_NUM.getType();
            paasRedisHelper.removeValue(RedisPrefixConstant.VALUE_ADDED, key);
            String userName = formDeleteDTO.getLoginUserName();
            // 记录日志
            String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_DELETE_FORM), userName, paasFormEntity.getName());
            mongoLogHelp.buildLog(corpid, formDeleteDTO.getUserId(), userName, OperateModuleTypeEnum.PAAS_FORM, OperateTypeEnum.DELETE,
                    paasFormEntity.getId().toString(), paasFormEntity.getName(), memo, formDeleteDTO.getHttpHeader());

        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("PaasFormServiceImpl.deleteByPackage  出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return formDeleteVO;
    }
    @Override
    public BusinessFieldVO businessFieldList(BusinessFieldDTO businessFieldDTO) throws XbbException {
        BusinessFieldVO businessFieldVO = new BusinessFieldVO();
        Integer fieldType = businessFieldDTO.getFieldType();
        // 保证businessType为100
        if (Objects.equals(businessFieldDTO.getBusinessType(), XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode())) {
            List<BusinessFieldPojo> fieldList = new ArrayList<>(40);
            BusinessFieldPojo pojo;
            // (客户名称）只支持工商查询的企业名称，
            if (Objects.equals(businessFieldDTO.getAttr(), CustomerManagementEnum.NAME.getAttr())) {
                BusinessSearchEnum businessSearchEnum = BusinessSearchEnum.ENTERPRISE_NAME;
                pojo = new BusinessFieldPojo();
                BeanUtils.copyProperties(businessSearchEnum, pojo);
                fieldList.add(pojo);
                businessFieldVO.setFieldList(fieldList);
                return businessFieldVO;
            }

            // (客户电话）只支持工商查询的联系电话，
            if (Objects.equals(businessFieldDTO.getAttr(), CustomerManagementEnum.PHONE.getAttr())) {
                BusinessSearchEnum businessSearchEnum = BusinessSearchEnum.MOBILE;
                pojo = new BusinessFieldPojo();
                BeanUtils.copyProperties(businessSearchEnum, pojo);
                fieldList.add(pojo);
                businessFieldVO.setFieldList(fieldList);
                return businessFieldVO;
            }

            //（客户地址）只支持工商查询的地址
            if (Objects.equals(businessFieldDTO.getAttr(), CustomerManagementEnum.ADDRESS.getAttr())) {
                BusinessSearchEnum businessSearchEnum = BusinessSearchEnum.REGISTER_ADDRESS;
                pojo = new BusinessFieldPojo();
                BeanUtils.copyProperties(businessSearchEnum, pojo);
                fieldList.add(pojo);
                businessFieldVO.setFieldList(fieldList);
                return businessFieldVO;
            }

            for (BusinessSearchEnum businessSearchEnum : BusinessSearchEnum.values()) {
                pojo = new BusinessFieldPojo();
                BeanUtils.copyProperties(businessSearchEnum, pojo);
                // 下拉框中的工商查询不支持子表单
                if (Objects.equals(fieldType, FieldTypeEnum.COMBO.getType())) {
                    boolean combo = businessSearchEnum.getFieldType().equals(FieldTypeEnum.TEXT.getType()) || businessSearchEnum.getFieldType().equals(FieldTypeEnum.NUM.getType());
                    if (businessSearchEnum.getParent() == 0 && combo) {
                        fieldList.add(pojo);
                    }
                }
                if (businessSearchEnum.getFieldType().equals(fieldType)) {
                    if (FieldTypeEnum.SUB_FORM.getType().equals(fieldType)) {
                        List<BusinessFieldPojo> childField = new ArrayList<>(10);
                        List<BusinessSearchEnum> childEnumList = BusinessSearchEnum.getByParentId(businessSearchEnum.getCode());
                        for (BusinessSearchEnum childEnum : childEnumList) {
                            BusinessFieldPojo child = new BusinessFieldPojo();
                            BeanUtils.copyProperties(childEnum, child);
                            childField.add(child);
                        }
                        pojo.setChildField(childField);
                        fieldList.add(pojo);
                    } else if (businessSearchEnum.getParent() == 0) {
                        fieldList.add(pojo);
                    }
                }
            }
            businessFieldVO.setFieldList(fieldList);
        }
        return businessFieldVO;
    }

    @Override
    public ClueConvertRuleVO getClueConvertRule(ClueConvertRuleSaveDTO formListDTO) throws XbbException {
        ClueConvertRuleVO clueConvertRuleVO = new ClueConvertRuleVO();
        Long formId = formListDTO.getFormId();
        String corpid = formListDTO.getCorpid();
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("del", DelEnum.NORMAL.getDel());
        param.put("formId", formId);
        if (Objects.nonNull(formListDTO.getCustomerFormId())) {
            param.put("customerFormId", formListDTO.getCustomerFormId());
        }
        param.put("del", 0);
        List<ClueConvertRuleEntity> ruleEntitys = clueConvertRuleModel.findEntitys(param);
        int index = 0;
        if (CollectionsUtil.isNotEmpty(ruleEntitys) && Objects.nonNull(ruleEntitys.get(0).getCustomerFormId())) {
            for(int i = 0; i<ruleEntitys.size() ;i++){
                ClueConvertRuleEntity temp = ruleEntitys.get(i);
                Long customerFormId = temp.getCustomerFormId();
                List<Long> customerFormIds = JSONArray.parseArray(temp.getCustomerFormIds(), Long.class);
                Long id = customerFormIds.get(0);
                if(Objects.equals(id,customerFormId)){
                    index = i;
                    break;
                }
            }
            formListDTO.setCustomerFormId(ruleEntitys.get(index).getCustomerFormId());
        }
        Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("corpid", corpid);
        map.put("businessType", XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
        if (Objects.nonNull(formListDTO.getCustomerFormId())) {
            map.put("id", formListDTO.getCustomerFormId());
        }
        map.put("del", 0);
        map.put("enable", 1);
        List<PaasFormEntityExt> customerList = paasFormModel.list(map);
        Iterator<PaasFormEntityExt> iterator = customerList.iterator();
        while (iterator.hasNext()){
            PaasFormEntityExt entityExt = iterator.next();
            List<OptionalRangeEntity> permissions = getPermissions(entityExt);
            Boolean noPermission = CollectionsUtil.isNotEmpty(permissions) && paasFormHelp.haveNoPermission(formListDTO.getLoginUser(), permissions);
            if (noPermission) {
                iterator.remove();
            }
        }
        if (CollectionsUtil.isEmpty(customerList)) {
            throw new XbbException(ClueErrorCodeEnum.API_ERROR_1110013);
        }
        PaasFormEntityExt customerForm = customerList.get(0);
        PaasFormExplainEntity customerExplain = paasFormExplainModel.getByFormId(customerForm.getId(), corpid);
        if (Objects.isNull(customerExplain)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }
        Map<String, FieldAttrEntity> customerExplainMap = ExplainUtil.getExplainMap(customerExplain.getExplains());

        PaasFormExplainEntity clueExplain = paasFormExplainModel.getByFormId(formId, corpid);
        Map<String, FieldAttrEntity> clueExplainMap = ExplainUtil.getExplainMap(clueExplain.getExplains());

        Map<String, String> relationAttrMap = ClueConverDefaultEnum.getRelationAttrMap(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
        JSONArray finalRuleObj = new JSONArray();
        if (CollectionsUtil.isNotEmpty(ruleEntitys)) {
            ClueConvertRuleEntity clueConvertRuleEntity = ruleEntitys.get(index);
            String convertRules = clueConvertRuleEntity.getConvertRules();
            JSONArray array = JSONArray.parseArray(convertRules);
            for (Object object : array) {
                JSONObject obj = new JSONObject();
                JSONObject jsonObject = (JSONObject) object;
                for (Map.Entry<String, Object> entrySet : jsonObject.entrySet()) {
                    String key = entrySet.getKey();
                    String value = (String) entrySet.getValue();

                    FieldAttrEntity clueAttrEntity = clueExplainMap.get(key);
                    FieldAttrEntity customerAttrEntity = customerExplainMap.get(value);
                    if (key.startsWith("subForm_")) {
                        // 子表单处理
                        String[] subKeyAttr = key.split("\\.");
                        if (subKeyAttr.length != 2) {
                            continue;
                        }
                        key = subKeyAttr[0];
                        String subKey = subKeyAttr[1];
                        clueAttrEntity = clueExplainMap.get(key);
                        if (Objects.isNull(clueAttrEntity) || Objects.equals(clueAttrEntity.getIsOpen(), 0)) {
                            continue;
                        }
                        for (FieldAttrEntity subField : clueAttrEntity.getSubForm().getItems()) {
                            if (Objects.equals(subField.getAttr(), subKey)) {
                                FieldAttrEntity attrEntity = new FieldAttrEntity();
                                BeanUtil.copyProperties(subField, attrEntity);
                                attrEntity.setAttr(key + "." + subKey);
                                attrEntity.setAttrName(clueAttrEntity.getAttrName() + "." + subField.getAttrName());
                                obj.put("left", attrEntity);
                            }
                        }
                    } else {
                        if (Objects.isNull(clueAttrEntity) || Objects.equals(clueAttrEntity.getIsOpen(), 0)) {
                            continue;
                        }
                        obj.put("left", clueAttrEntity);
                    }
                    if (value.startsWith("subForm_")) {
                        // 子表单处理
                        String[] subValueAttr = value.split("\\.");
                        if (subValueAttr.length != 2) {
                            continue;
                        }
                        value = subValueAttr[0];
                        String subValue = subValueAttr[1];
                        customerAttrEntity = customerExplainMap.get(value);
                        if (Objects.isNull(customerAttrEntity) || Objects.equals(customerAttrEntity.getIsOpen(), 0)) {
                            continue;
                        }
                        for (FieldAttrEntity subField : customerAttrEntity.getSubForm().getItems()) {
                            if (Objects.equals(subField.getAttr(), subValue)) {
                                FieldAttrEntity attrEntity = new FieldAttrEntity();
                                BeanUtil.copyProperties(subField, attrEntity);
                                attrEntity.setAttr(value + "." + subValue);
                                attrEntity.setAttrName(customerAttrEntity.getAttrName() + "." + subField.getAttrName());
                                obj.put("right", attrEntity);
                            }
                        }
                    } else {
                        if (Objects.isNull(customerAttrEntity) || Objects.equals(customerAttrEntity.getIsOpen(), 0)) {
                            continue;
                        }
                        obj.put("right", customerAttrEntity);
                    }
                }
                if(Objects.nonNull(obj)&&obj.size()!=0){
                    finalRuleObj.add(obj);
                }
            }
            if (StringUtil.isNotEmpty(clueConvertRuleEntity.getCustomerFormIds())) {
                List<Long> customerFormIds = JSONArray.parseArray(clueConvertRuleEntity.getCustomerFormIds(), Long.class);
                clueConvertRuleVO.setCustomerFormIds(customerFormIds);
            }
            clueConvertRuleVO.setId(clueConvertRuleEntity.getId());
        } else {
            for (Map.Entry<String, String> entry : relationAttrMap.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();

                FieldAttrEntity clueAttrEntity = clueExplainMap.get(key);
                FieldAttrEntity customerAttrEntity = customerExplainMap.get(value);
                JSONObject obj = new JSONObject();
                if (key.startsWith("subForm_")) {
                    // 子表单处理
                    String[] subKeyAttr = key.split("\\.");
                    if (subKeyAttr.length !=2) {
                        continue;
                    }
                    key = subKeyAttr[0];
                    String subKey = subKeyAttr[1];
                    clueAttrEntity = clueExplainMap.get(key);
                    if (Objects.isNull(clueAttrEntity) || Objects.equals(clueAttrEntity.getIsOpen(), 0)) {
                        continue;
                    }
                    for (FieldAttrEntity subField : clueAttrEntity.getSubForm().getItems()) {
                        if (Objects.equals(subField.getAttr(), subKey)) {
                            FieldAttrEntity attrEntity = new FieldAttrEntity();
                            BeanUtil.copyProperties(subField, attrEntity);
                            attrEntity.setAttr(key + "." + subKey);
                            attrEntity.setAttrName(clueAttrEntity.getAttrName() + "." + subField.getAttrName());
                            obj.put("left", attrEntity);
                        }
                    }
                } else {
                    if (Objects.isNull(clueAttrEntity) || Objects.equals(clueAttrEntity.getIsOpen(), 0)) {
                        continue;
                    }
                    obj.put("left", clueAttrEntity);
                }
                if (value.startsWith("subForm_")) {
                    // 子表单处理
                    String[] subValueAttr = value.split("\\.");
                    if (subValueAttr.length !=2) {
                        continue;
                    }
                    value = subValueAttr[0];
                    String subValue = subValueAttr[1];
                    customerAttrEntity = customerExplainMap.get(value);
                    if (Objects.isNull(customerAttrEntity) || Objects.equals(customerAttrEntity.getIsOpen(), 0)) {
                        continue;
                    }
                    for (FieldAttrEntity subField : customerAttrEntity.getSubForm().getItems()) {
                        if (Objects.equals(subField.getAttr(), subValue)) {
                            FieldAttrEntity attrEntity = new FieldAttrEntity();
                            BeanUtil.copyProperties(subField, attrEntity);
                            attrEntity.setAttr(value + "." + subValue);
                            attrEntity.setAttrName(customerAttrEntity.getAttrName() + "." + subField.getAttrName());
                            obj.put("right", attrEntity);
                        }
                    }
                } else {
                    if (Objects.isNull(customerAttrEntity) || Objects.equals(customerAttrEntity.getIsOpen(), 0)) {
                        continue;
                    }
                    obj.put("right", customerAttrEntity);
                }
                if(Objects.nonNull(obj)&&obj.size()!=0){
                    finalRuleObj.add(obj);
                }
            }
            clueConvertRuleVO.setCustomerFormIds(Collections.singletonList(customerForm.getId()));
        }
        clueConvertRuleVO.setCustomerFormId(customerForm.getId());
        clueConvertRuleVO.setConvertRule(finalRuleObj);
        return clueConvertRuleVO;
    }

    @Override
    public BaseVO clueConverSave(ClueConvertRuleSaveDTO clueConvertRuleSaveDTO) throws XbbException {
        /*Long formId = clueConvertRuleSaveDTO.getFormId();
        Long customerFormId = clueConvertRuleSaveDTO.getCustomerFormId();
        String corpid = clueConvertRuleSaveDTO.getCorpid();
        JSONArray convertRule = clueConvertRuleSaveDTO.getConvertRule();
        if (Objects.isNull(convertRule) || convertRule.isEmpty()) {
            throw new XbbException(ErrorCodeEnum.API_ERROR_1110019);
        }
        ClueConvertRuleEntity clueConvertRuleEntity = clueConvertRuleModel.getByCorpidAndFormId(corpid, formId);
//        ClueConvertRuleEntity clueConvertRuleEntity = clueConvertRuleModel.getByCustomerFormId(corpid, formId,customerFormId);
        Long now = DateTimeUtil.getInt();
        if (Objects.isNull(clueConvertRuleEntity)) {
            clueConvertRuleEntity = new ClueConvertRuleEntity();
            clueConvertRuleEntity.setAddTime(now);
            clueConvertRuleEntity.setUpdateTime(now);
            clueConvertRuleEntity.setConvertRules(convertRule.toJSONString());
            clueConvertRuleEntity.setFormId(formId);
            clueConvertRuleEntity.setCustomerFormId(customerFormId);
            clueConvertRuleEntity.setCorpid(corpid);
            clueConvertRuleEntity.setDel(DelEnum.NORMAL.getDel());
        } else {
            clueConvertRuleEntity.setCustomerFormId(customerFormId);
            clueConvertRuleEntity.setUpdateTime(now);
            clueConvertRuleEntity.setConvertRules(convertRule.toJSONString());
        }
        clueConvertRuleEntity.setCustomerFormIds(clueConvertRuleSaveDTO.getCustomerFormIds().toString());
        clueConvertRuleModel.save(clueConvertRuleEntity);*/
        return new BaseVO();
    }

    @Override
    public BaseVO clueConverRulesListSave(ClueConvertRulesListSaveDTO clueConvertRulesListSaveDTO) throws XbbException {
        Long formId = clueConvertRulesListSaveDTO.getFormId();
        Long customerFormId = clueConvertRulesListSaveDTO.getCustomerFormId();
        String corpid = clueConvertRulesListSaveDTO.getCorpid();
        JSONArray convertRule = clueConvertRulesListSaveDTO.getConvertRule();
        List<ClueConvertRulesListDTO> rulesList = clueConvertRulesListSaveDTO.getRulesList();
//        if (Objects.isNull(convertRule) || convertRule.isEmpty()) {
//            throw new XbbException(ErrorCodeEnum.API_ERROR_1110019);
//        }
       for(ClueConvertRulesListDTO temp: rulesList){
           Long customerFormIdTemp = temp.getCustomerFormId();
           JSONArray convertRuleTemp = temp.getConvertRule();
           ClueConvertRuleEntity clueConvertRuleEntity = clueConvertRuleModel.getByCustomerFormId(corpid, formId,customerFormIdTemp);
//           ClueConvertRuleEntity clueConvertRuleEntity = clueConvertRuleModel.getByCustomerFormId(corpid, formId,customerFormId);
           Long now = DateTimeUtil.getInt();
           if (Objects.isNull(clueConvertRuleEntity)) {
               clueConvertRuleEntity = new ClueConvertRuleEntity();
               clueConvertRuleEntity.setAddTime(now);
               clueConvertRuleEntity.setUpdateTime(now);
               clueConvertRuleEntity.setConvertRules(convertRuleTemp.toJSONString());
               clueConvertRuleEntity.setFormId(formId);
               clueConvertRuleEntity.setCustomerFormId(customerFormIdTemp);
               clueConvertRuleEntity.setCorpid(corpid);
               clueConvertRuleEntity.setDel(DelEnum.NORMAL.getDel());
           } else {
               clueConvertRuleEntity.setCustomerFormId(customerFormIdTemp);
               clueConvertRuleEntity.setUpdateTime(now);
               clueConvertRuleEntity.setConvertRules(convertRuleTemp.toJSONString());
           }
           clueConvertRuleEntity.setCustomerFormIds(clueConvertRulesListSaveDTO.getCustomerFormIds().toString());
           clueConvertRuleModel.save(clueConvertRuleEntity);
       }
        List<ClueConvertRuleEntity> clueConvertRuleEntityList = clueConvertRuleModel.getByCorpidAndFormId(corpid, formId);
        for(ClueConvertRuleEntity clueConvertRuleEntity:clueConvertRuleEntityList){
            clueConvertRuleEntity.setCustomerFormIds(clueConvertRulesListSaveDTO.getCustomerFormIds().toString());
            clueConvertRuleModel.save(clueConvertRuleEntity);
        }

        return new BaseVO();
    }

    @Override
    public SupportLinkageFieldsVO supportLinkageFields(ClueConvertRuleSaveDTO clueConvertRuleSaveDTO) throws XbbException {
        SupportLinkageFieldsVO supportLinkageFieldsVO = new SupportLinkageFieldsVO();
        Long formId = clueConvertRuleSaveDTO.getFormId();
        Integer originType = clueConvertRuleSaveDTO.getOriginType();
        if (originType == null) { // 附默认值
            originType = 1;
        }
        PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(formId, clueConvertRuleSaveDTO.getCorpid());
        if (Objects.isNull(paasFormExplainEntity)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001.getCode(), MessageConstant.THIS_EXPLAIN_NOT_EXIST);
        }

        List<FieldAttrEntity> fieldList = JSON.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);

        List<FieldAttrEntity> supportFields = new ArrayList<>();

        List<Integer> supportLinkageFields = new ArrayList<>();
        Object clazz = new LinkDisplayConstant();
        for (FieldTypeEnum fieldTypeEnum : FieldTypeEnum.values()) {
            // 除了字段映射，其他不支持图片和附件
            if (originType != 2
                    && (Objects.equals(fieldTypeEnum.getType(), FieldTypeEnum.UPLOAD.getType()) || Objects.equals(fieldTypeEnum.getType(), FieldTypeEnum.IMAGE.getType()))) {
                continue;
            }
            if (ReflectHelper.exist(clazz, fieldTypeEnum.name())) {
                Integer[] array = (Integer[]) ReflectHelper.valueGet(clazz, fieldTypeEnum.getAlias().toUpperCase());
                List<Integer> list = new ArrayList<>();
                for (Integer integer : array) {
                    list.add(integer);
                }
                supportLinkageFields.add(fieldTypeEnum.getType());
            }
        }
        List<String> unsopportAttr = new ArrayList<>();
        if (Objects.equals(XbbRefTypeEnum.CLUE.getCode(), paasFormExplainEntity.getBusinessType())) {
            unsopportAttr.add(ClueEnum.SCORE.getAttr());
            unsopportAttr.add(ClueEnum.MARKET_ACTIVITY_NAME.getAttr());
            unsopportAttr.add(ClueEnum.LAST_CONNECT_TIME.getAttr());
            unsopportAttr.add(ClueEnum.BACK_PUBLIC_DATE.getAttr());
            unsopportAttr.add(ClueEnum.DISTRIBUTION_DATE.getAttr());
        }
        for (FieldAttrEntity fieldAttrEntity : fieldList) {
            Integer fieldType = fieldAttrEntity.getFieldType();
            String attr = fieldAttrEntity.getAttr();
            if (!supportLinkageFields.contains(fieldType)) {
                continue;
            }
            if (ExplainUtil.isSubFormNoSelectProduct(fieldType)) {
                List<? extends FieldAttrEntity> subExplainList = fieldAttrEntity.getSubForm().getItems();
                for (FieldAttrEntity subAttrEntity : subExplainList) {
                    Integer subFieldType = subAttrEntity.getFieldType();
                    if (!supportLinkageFields.contains(subFieldType)) {
                        continue;
                    }
                    String subAttr = subAttrEntity.getAttr();
                    subAttrEntity.setAttr(attr + "." + subAttr);
                    subAttrEntity.setAttrName(fieldAttrEntity.getAttrName() + "." + subAttrEntity.getAttrName());
                    supportFields.add(subAttrEntity);
                }
            } else {
                if (unsopportAttr.contains(attr)) {
                    continue;
                }
                supportFields.add(fieldAttrEntity);
            }
        }
        supportLinkageFieldsVO.setFieldEntitys(supportFields);
        return supportLinkageFieldsVO;
    }

    @Override
    public BusinessFieldVO fineClueFieldList(BusinessFieldDTO businessFieldDTO) throws XbbException {
        BusinessFieldVO businessFieldVO = new BusinessFieldVO();
        Integer fieldType = businessFieldDTO.getFieldType();
        // 保证businessType为100客户或者线索8000
        if (fineClueHelp.hasBusinessSearch(businessFieldDTO.getBusinessType())) {
            List<BusinessFieldPojo> fieldList = new ArrayList<>();
            BusinessFieldPojo pojo;
            // (客户名称,企业名称）只支持工商查询的企业名称，
            if (fineClueHelp.isMainAttr(businessFieldDTO.getAttr())) {
                BusinessFineClueEnum businessFineClueEnum = BusinessFineClueEnum.ENTERPRISE_NAME;
                pojo = new BusinessFieldPojo();
                BeanUtils.copyProperties(businessFineClueEnum, pojo);
                fieldList.add(pojo);
                businessFieldVO.setFieldList(fieldList);
                return businessFieldVO;
            } else if (fineClueHelp.isAddressAttr(businessFieldDTO.getAttr())) {
                //（客户地址）只支持工商查询的地址
                BusinessFineClueEnum fineClueEnum = BusinessFineClueEnum.REGISTERED_ADDRESS;
                pojo = new BusinessFieldPojo();
                BeanUtils.copyProperties(fineClueEnum, pojo);
                fieldList.add(pojo);
                businessFieldVO.setFieldList(fieldList);
                return businessFieldVO;
            }

            for (BusinessFineClueEnum fineClueEnum : BusinessFineClueEnum.values()) {
                pojo = new BusinessFieldPojo();
                BeanUtils.copyProperties(fineClueEnum, pojo);
                // 下拉框中的工商查询不支持子表单
                if (Objects.equals(fieldType, FieldTypeEnum.COMBO.getType())) {
                    boolean combo = fineClueEnum.getFieldType().equals(FieldTypeEnum.TEXT.getType()) || fineClueEnum.getFieldType().equals(FieldTypeEnum.NUM.getType());
                    if (fineClueEnum.getParent() == 0 && combo) {
                        fieldList.add(pojo);
                    }
                }
                if (fineClueEnum.getFieldType().equals(fieldType)) {
                    if (FieldTypeEnum.SUB_FORM.getType().equals(fieldType)) {
                        List<BusinessFieldPojo> childField = new ArrayList<>();
                        List<BusinessFineClueEnum> childEnumList = BusinessFineClueEnum.getByParentId(fineClueEnum.getCode());
                        for (BusinessFineClueEnum childEnum : childEnumList) {
                            BusinessFieldPojo child = new BusinessFieldPojo();
                            BeanUtils.copyProperties(childEnum, child);
                            childField.add(child);
                        }
                        pojo.setChildField(childField);
                        fieldList.add(pojo);
                    } else if (fineClueEnum.getParent() == 0) {
                        fieldList.add(pojo);
                    }
                }
            }
            businessFieldVO.setFieldList(fieldList);
        }
        return businessFieldVO;
    }

    @Override
    public FieldConvertRuleVO getFieldConvertRule(FieldConvertRuleDTO fieldConvertRuleDTO) throws XbbException {
        FieldConvertRuleVO fieldConvertRuleVO = new FieldConvertRuleVO();
        Long originFormId = fieldConvertRuleDTO.getOriginFormId();
        Long targetFormId = fieldConvertRuleDTO.getTargetFormId();
        String corpid = fieldConvertRuleDTO.getCorpid();
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("del", DelEnum.NORMAL.getDel());
        param.put("originFormId", originFormId);
        List<FieldConvertRuleEntity> ruleEntitys = fieldConvertRuleModel.findEntitys(param);
        // 已保存的所有表单的id,并把多余的数据移除
        ArrayList<Long> formIds = new ArrayList<>();
        if (CollectionsUtil.isNotEmpty(ruleEntitys)) {
            Iterator<FieldConvertRuleEntity> iterator = ruleEntitys.iterator();
            while (iterator.hasNext()) {
                FieldConvertRuleEntity ruleEntity = iterator.next();
                formIds.add(ruleEntity.getTargetFormId());
                if (Objects.nonNull(targetFormId) && !targetFormId.equals(ruleEntity.getTargetFormId())) {
                    iterator.remove();
                }
            }
        }

        PaasFormExplainEntity originFormExplain = paasFormExplainModel.getByFormId(originFormId, corpid);
        Map<String, FieldAttrEntity> originExplainMap = ExplainUtil.getExplainMap(originFormExplain.getExplains());

        Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("corpid", corpid);
        if (Objects.nonNull(targetFormId)) {
            map.put("id", targetFormId);
        } else {
            // 线索默认带出客户的
            if (Objects.equals(XbbRefTypeEnum.CLUE.getCode(), originFormExplain.getBusinessType())) {
                map.put("businessType", XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
            } else if (CollectionsUtil.isEmpty(ruleEntitys)) {
                return new FieldConvertRuleVO();
            }
        }
        map.put("del", 0);
        map.put("enable", 1);
        List<PaasFormEntityExt> targetFormList = paasFormModel.list(map);
        List<Long> targetFormIdList = new ArrayList<>(targetFormList.size());
        Iterator<PaasFormEntityExt> iterator = targetFormList.iterator();
        while (iterator.hasNext()){
            PaasFormEntityExt entityExt = iterator.next();
            targetFormIdList.add(entityExt.getId());
            List<OptionalRangeEntity> permissions = getPermissions(entityExt);
            Boolean noPermission = CollectionsUtil.isNotEmpty(permissions) && paasFormHelp.haveNoPermission(fieldConvertRuleDTO.getLoginUser(), permissions);
            if (noPermission) {
                iterator.remove();
            }
        }
        if (CollectionsUtil.isEmpty(targetFormList)) {
            throw new XbbException(ProErrorCodeEnum.API_ERROR_260023);
        } else {
            // 移除不可见数据
            Collection<Long> intersection = org.apache.commons.collections4.CollectionUtils.intersection(targetFormIdList, formIds);
            formIds.clear();
            formIds.addAll(intersection);
        }
        PaasFormEntityExt targetForm = targetFormList.get(0);
        if (CollectionsUtil.isNotEmpty(formIds)) {
            for (PaasFormEntityExt paasFormEntityExt : targetFormList) {
                if (Objects.equals(paasFormEntityExt.getId(), formIds.get(0))) {
                    targetForm = paasFormEntityExt;
                    break;
                }
            }
        }
        targetFormId = targetForm.getId();
        PaasFormExplainEntity targetFormExplain = paasFormExplainModel.getByFormId(targetForm.getId(), corpid);
        if (Objects.isNull(targetFormExplain)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }
        Map<String, FieldAttrEntity> targetExplainMap = ExplainUtil.getExplainMap(targetFormExplain.getExplains());
        // 获取默认规则
        Map<String, String> relationAttrMap = FieldConvertDefaultEnum.getRelationAttrMap(targetForm.getBusinessType());
        JSONArray finalRuleObj = new JSONArray();
        FieldConvertRuleEntity fieldConvertRuleEntity = null;
        if (CollectionsUtil.isNotEmpty(ruleEntitys)) {
            for (FieldConvertRuleEntity ruleEntity : ruleEntitys) {
                if (Objects.equals(ruleEntity.getTargetFormId(), targetFormId)) {
                    fieldConvertRuleEntity = ruleEntity;
                }
            }
        }
        if (Objects.nonNull(fieldConvertRuleEntity)) {
            String convertRules = fieldConvertRuleEntity.getConvertRules();
            JSONArray array = JSONArray.parseArray(convertRules);
            rule: for (Object object : array) {
                JSONObject obj = new JSONObject();
                JSONObject jsonObject = (JSONObject) object;
                for (Map.Entry<String, Object> entrySet : jsonObject.entrySet()) {
                    String key = entrySet.getKey();
                    String value = (String) entrySet.getValue();
                    // 子表单处理
                    String subKey = "";
                    String subValue = "";
                    if (key.startsWith("subForm_")) {
                        String[] subKeyAttr = key.split("\\.");
                        if (subKeyAttr.length != 2) {
                            continue;
                        }
                        key = subKeyAttr[0];
                        subKey = subKeyAttr[1];
                    }
                    if (value.startsWith("subForm_")) {
                        String[] subValueAttr = value.split("\\.");
                        if (subValueAttr.length != 2) {
                            continue;
                        }
                        value = subValueAttr[0];
                        subValue = subValueAttr[1];
                    }

                    FieldAttrEntity originAttrEntity = originExplainMap.get(key);
                    FieldAttrEntity targetAttrEntity = targetExplainMap.get(value);
                    // 任何一个表单attr不存在就过滤掉这个规则
                    if (Objects.isNull(targetAttrEntity) || Objects.equals(targetAttrEntity.getIsOpen(), 0)
                            || Objects.isNull(originAttrEntity) || Objects.equals(originAttrEntity.getIsOpen(), 0)) {
                        continue;
                    }
                    // 处理源值
                    if (key.startsWith("subForm_")) {
                        // 子表单处理
                        for (FieldAttrEntity subField : originAttrEntity.getSubForm().getItems()) {
                            if (Objects.equals(subField.getAttr(), subKey)) {
                                FieldAttrEntity attrEntity = new FieldAttrEntity();
                                BeanUtil.copyProperties(subField, attrEntity);
                                attrEntity.setAttr(key + "." + subKey);
                                attrEntity.setAttrName(originAttrEntity.getAttrName() + "." + subField.getAttrName());
                                obj.put("left", attrEntity);
                            }
                        }
                        // 子表单内一个attr为空，移除这个规则
                        if (!obj.containsKey("left")) {
                            continue rule;
                        }
                    } else {
                        obj.put("left", originAttrEntity);
                    }
                    // 处理目标值
                    if (value.startsWith("subForm_")) {
                        // 子表单处理
                        for (FieldAttrEntity subField : targetAttrEntity.getSubForm().getItems()) {
                            if (Objects.equals(subField.getAttr(), subValue)) {
                                FieldAttrEntity attrEntity = new FieldAttrEntity();
                                BeanUtil.copyProperties(subField, attrEntity);
                                attrEntity.setAttr(value + "." + subValue);
                                attrEntity.setAttrName(targetAttrEntity.getAttrName() + "." + subField.getAttrName());
                                obj.put("right", attrEntity);
                            }
                        }
                        // 子表单内一个attr为空，移除这个规则
                        if (!obj.containsKey("left") || !obj.containsKey("right")) {
                            continue rule;
                        }
                    } else {
                        obj.put("right", targetAttrEntity);
                    }
                }
                if (obj.size() > 0) {
                    finalRuleObj.add(obj);
                }
            }
            fieldConvertRuleVO.setFormIds(formIds);
            fieldConvertRuleVO.setId(fieldConvertRuleEntity.getId());
        } else {
            for (Map.Entry<String, String> entry : relationAttrMap.entrySet()) {
                JSONObject obj = new JSONObject();
                String key = entry.getKey();
                String value = entry.getValue();
                // 子表单处理
                String subKey = "";
                String subValue = "";
                if (key.startsWith("subForm_")) {
                    String[] subKeyAttr = key.split("\\.");
                    if (subKeyAttr.length != 2) {
                        continue;
                    }
                    key = subKeyAttr[0];
                    subKey = subKeyAttr[1];
                }
                if (value.startsWith("subForm_")) {
                    String[] subValueAttr = value.split("\\.");
                    if (subValueAttr.length != 2) {
                        continue;
                    }
                    value = subValueAttr[0];
                    subValue = subValueAttr[1];
                }

                FieldAttrEntity originAttrEntity = originExplainMap.get(key);
                FieldAttrEntity targetAttrEntity = targetExplainMap.get(value);
                // 任何一个表单attr不存在就过滤掉这个规则
                if (Objects.isNull(targetAttrEntity) || Objects.equals(targetAttrEntity.getIsOpen(), 0)
                        || Objects.isNull(originAttrEntity) || Objects.equals(originAttrEntity.getIsOpen(), 0)) {
                    continue;
                }
                // 处理源值
                if (key.startsWith("subForm_")) {
                    for (FieldAttrEntity subField : originAttrEntity.getSubForm().getItems()) {
                        if (Objects.equals(subField.getAttr(), subKey)) {
                            FieldAttrEntity attrEntity = new FieldAttrEntity();
                            BeanUtil.copyProperties(subField, attrEntity);
                            attrEntity.setAttr(key + "." + subKey);
                            attrEntity.setAttrName(originAttrEntity.getAttrName() + "." + subField.getAttrName());
                            obj.put("left", attrEntity);
                        }
                    }
                    // 子表单内一个attr为空，移除这个规则
                    if (!obj.containsKey("left")) {
                        continue;
                    }
                } else {
                    obj.put("left", originAttrEntity);
                }
                // 处理目标值
                if (value.startsWith("subForm_")) {
                    for (FieldAttrEntity subField : targetAttrEntity.getSubForm().getItems()) {
                        if (Objects.equals(subField.getAttr(), subValue)) {
                            FieldAttrEntity attrEntity = new FieldAttrEntity();
                            BeanUtil.copyProperties(subField, attrEntity);
                            attrEntity.setAttr(value + "." + subValue);
                            attrEntity.setAttrName(targetAttrEntity.getAttrName() + "." + subField.getAttrName());
                            obj.put("right", attrEntity);
                        }
                    }
                    // 子表单内一个attr为空，移除这个规则
                    if (!obj.containsKey("left") || !obj.containsKey("right")) {
                        continue;
                    }
                } else {
                    obj.put("right", targetAttrEntity);
                }
                if (obj.size() > 0) {
                    finalRuleObj.add(obj);
                }
            }
            fieldConvertRuleVO.setFormIds(Collections.singletonList(targetForm.getId()));
        }
        fieldConvertRuleVO.setFormId(targetForm.getId());
        fieldConvertRuleVO.setConvertRule(finalRuleObj);
        return fieldConvertRuleVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseVO fieldConvertSave(FieldConvertRuleDTO fieldConvertRuleDTO) throws XbbException {
        Long originFormId = fieldConvertRuleDTO.getOriginFormId();
        Long targetFormId = fieldConvertRuleDTO.getTargetFormId();
        String corpid = fieldConvertRuleDTO.getCorpid();
        Long ruleId = fieldConvertRuleDTO.getId();
        JSONArray convertRule = fieldConvertRuleDTO.getConvertRule();
        if (Objects.isNull(convertRule) || convertRule.isEmpty()) {
            throw new XbbException(ClueErrorCodeEnum.API_ERROR_1110019);
        }
        Long now = DateTimeUtil.getInt();
        List<Long> targetFormIds = fieldConvertRuleDTO.getTargetFormIds();
        // 处理删除的逻辑
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put("corpid", corpid);
        params.put("originFormId", originFormId);
        params.put("del", DelEnum.NORMAL.getDel());
        List<FieldConvertRuleEntity> originRuleList = fieldConvertRuleModel.findEntitys(params);
        boolean isChange = false;
        if (CollectionsUtil.isNotEmpty(originRuleList) && CollectionsUtil.isNotEmpty(targetFormIds)) {
            Iterator<FieldConvertRuleEntity> ruleEntityIterator = originRuleList.iterator();
            while (ruleEntityIterator.hasNext()) {
                FieldConvertRuleEntity fieldConvertRuleEntity = ruleEntityIterator.next();
                if (targetFormIds.contains(fieldConvertRuleEntity.getTargetFormId())) {
                    ruleEntityIterator.remove();
                } else {
                    isChange = true;
                    fieldConvertRuleEntity.setDel(DelEnum.DELETE.getDel());
                    fieldConvertRuleEntity.setUpdateTime(now);
                }
            }
            // 没修改不需要更新
            if (isChange && CollectionsUtil.isNotEmpty(originRuleList)) {
                fieldConvertRuleModel.updateBatch(originRuleList, corpid);
            }
        }

        // 更新或插入
        FieldConvertRuleEntity fieldConvertRuleEntity;
        if (Objects.isNull(ruleId)) {
            fieldConvertRuleEntity = new FieldConvertRuleEntity();
            fieldConvertRuleEntity.setAddTime(now);
            fieldConvertRuleEntity.setUpdateTime(now);
            fieldConvertRuleEntity.setConvertRules(convertRule.toJSONString());
            fieldConvertRuleEntity.setOriginFormId(originFormId);
            fieldConvertRuleEntity.setTargetFormId(targetFormId);
            fieldConvertRuleEntity.setCorpid(corpid);
            fieldConvertRuleEntity.setDel(DelEnum.NORMAL.getDel());
            fieldConvertRuleModel.insert(fieldConvertRuleEntity);
        } else {
            fieldConvertRuleEntity = fieldConvertRuleModel.getByKey(ruleId, corpid);
            fieldConvertRuleEntity.setTargetFormId(targetFormId);
            fieldConvertRuleEntity.setUpdateTime(now);
            fieldConvertRuleEntity.setConvertRules(convertRule.toJSONString());
            fieldConvertRuleModel.update(fieldConvertRuleEntity);
        }
        return new BaseVO();
    }


    /**
     * 校验联动设置和关联其他表单的设置
     * @param fieldAttrEntity
     * @param attrName
     * @throws XbbException
     */
    private void validateComboType(FieldAttrEntity fieldAttrEntity, String attrName) throws XbbException {
        DefaultAttrPoJo defaultAttrPoJo = fieldAttrEntity.getDefaultAttr();
        Boolean dataRely = Objects.nonNull(defaultAttrPoJo) && Objects.equals(DefaultTypeEnum.DATARELY.getAlias(), defaultAttrPoJo.getDefaultType());
        // 下拉框数据联动，或者默认值为数据联动时，校验一下
        if (Objects.equals(fieldAttrEntity.getComboType(), ComboTypeEnum.DATARELY.getType()) || dataRely) {
            RelyPoJo relyPoJo = fieldAttrEntity.getDefaultAttr().getRely();
            if (Objects.isNull(relyPoJo)) {
                throw  new XbbException(ProErrorCodeEnum.API_ERROR_260008, String.format(ProErrorCodeEnum.API_ERROR_260008.getMsg(), attrName));
            }
            if (Objects.isNull(relyPoJo.getSourceFormId())) {
                throw  new XbbException(ProErrorCodeEnum.API_ERROR_260012, String.format(ProErrorCodeEnum.API_ERROR_260012.getMsg(), attrName));
            }
            // 当前表单的字段
            List<RelyConditionPoJo> condition = relyPoJo.getCondition();
            if (Objects.nonNull(condition)) {
                // 校验条件数量
                if (CollectionsUtil.isEmpty(condition)) {
                    throw new XbbException(ProErrorCodeEnum.API_ERROR_260026, ProErrorCodeEnum.API_ERROR_260026.getMsg(), attrName);
                }
                if (condition.size() > CONDITION_NUM) {
                    throw new XbbException(ProErrorCodeEnum.API_ERROR_260025, ProErrorCodeEnum.API_ERROR_260025.getMsg(), attrName);
                }
                for (RelyConditionPoJo conditionPoJo : condition) {
                    if (StringUtil.isEmpty(conditionPoJo.getDisplayField())) {
                        throw new XbbException(ProErrorCodeEnum.API_ERROR_260009, ProErrorCodeEnum.API_ERROR_260009.getMsg(), attrName);
                    }
                    if (StringUtil.isEmpty(conditionPoJo.getTargetField())) {
                        throw new XbbException(ProErrorCodeEnum.API_ERROR_260010, ProErrorCodeEnum.API_ERROR_260010.getMsg(), attrName);
                    }
                }
            } else {
                // 兼容以前的数据没有condition:[]
                if (StringUtil.isEmpty(relyPoJo.getDisplayField())) {
                    throw new XbbException(ProErrorCodeEnum.API_ERROR_260009, String.format(ProErrorCodeEnum.API_ERROR_260009.getMsg(), attrName));
                }
                if (StringUtil.isEmpty(relyPoJo.getTargetField())) {
                    throw new XbbException(ProErrorCodeEnum.API_ERROR_260010, String.format(ProErrorCodeEnum.API_ERROR_260010.getMsg(), attrName));
                }
            }
            // 联动显示的字段
            if (StringUtil.isEmpty(relyPoJo.getLinkField())) {
                throw  new XbbException(ProErrorCodeEnum.API_ERROR_260011, String.format(ProErrorCodeEnum.API_ERROR_260011.getMsg(), attrName));
            }
        } else if (Objects.equals(fieldAttrEntity.getComboType(), ComboTypeEnum.LINKFORM.getType())) {
            LinkFormPoJo linkFormPoJo = fieldAttrEntity.getLinkForm();
            if (Objects.isNull(linkFormPoJo)) {
                throw  new XbbException(ProErrorCodeEnum.API_ERROR_260008, String.format(ProErrorCodeEnum.API_ERROR_260008.getMsg(), attrName));
            }
            if (Objects.isNull(linkFormPoJo.getSourceFormId())) {
                throw  new XbbException(ProErrorCodeEnum.API_ERROR_260012, String.format(ProErrorCodeEnum.API_ERROR_260012.getMsg(), attrName));
            }
            // 联动显示的字段
            if (StringUtil.isEmpty(linkFormPoJo.getDisplayField())) {
                throw  new XbbException(ProErrorCodeEnum.API_ERROR_260011, String.format(ProErrorCodeEnum.API_ERROR_260011.getMsg(), attrName));
            }
        }

    }

    @Override
    public FormUpdateBusinessRuleVO updateBusinessRule(FormUpdateBusinessRuleDTO formUpdateBusinessRuleDTO) throws XbbException {
        FormUpdateBusinessRuleVO formUpdateBusinessRuleVO;
        try {
            formUpdateBusinessRuleVO = businessRuleInfoService.save(formUpdateBusinessRuleDTO);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("PaasFormServiceImpl.updateBusinessRule  出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return formUpdateBusinessRuleVO;
    }


    @Override
    public FormBusinessRuleVO businessRuleList(FormBusinessRuleDTO formBusinessRuleDTO) throws XbbException {
        FormBusinessRuleVO formBusinessRuleVO;
        try {
            Long formId = formBusinessRuleDTO.getFormId();
            String corpid = formBusinessRuleDTO.getCorpid();
            Integer businessType = formBusinessRuleDTO.getBusinessType();
            PaasFormEntity paasFormEntity = proFormHelp.getPaasForm(formId, businessType, corpid);
            if (Objects.isNull(paasFormEntity)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
            }
            formBusinessRuleVO = businessRuleInfoService.get(corpid, formId, businessType, formBusinessRuleDTO.getSaasMark(), 1);

            if(formBusinessRuleDTO.getLoginUser().isAdmin()) {
                formBusinessRuleVO.setUpgrade(1);
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("PaasFormServiceImpl.businessRuleList  出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return formBusinessRuleVO;
    }



    private void getFormIdIn(RuleTargetPojo ruleTargetPojo, Set<Long> formIdIn, Set<Long> workOrderFormIdIn) {
        if (Objects.equals(ruleTargetPojo.getLinkBusinessType(), XbbRefTypeEnum.WORK_ORDER.getCode())) {
            workOrderFormIdIn.add(ruleTargetPojo.getFormId());
        } else {
            formIdIn.add(ruleTargetPojo.getFormId());
        }
    }

    /**
     * saasHandel saas业务特殊处理
     * @param formGetDTO
     * @param explainList
     * @param enableJxc
     * @throws XbbException
     * @author 饶龙
     * @since v1.0
     * @version 资金管理
     * @update by zcp 处理回款单的字段解释：如果未开启预收款菜单，则隐藏与预收款相关的几个类型
     */
    private void saasHandel(FormGetDTO formGetDTO, List<FieldAttrEntity> explainList, Boolean enableJxc) throws XbbException {
        // 经销商转BusinessType
        Integer businessType = XbbRefTypeEnum.transferBusinessType4Distributor(formGetDTO.getBusinessType(), formGetDTO.getDistributorMark());
        List<Integer> workReportTypes = Arrays.asList(XbbRefTypeEnum.WORKREPORT_DAILY.getCode(), XbbRefTypeEnum.WORKREPORT_WEEKLY.getCode(), XbbRefTypeEnum.WORKREPORT_MONTHLY.getCode());
        Integer feeType = businessRuleUserPermissionHelp.getFeeType(formGetDTO.getCorpid());
        if (workReportTypes.contains(businessType)) {
            Integer type = null;
            if (Objects.equals(businessType,XbbRefTypeEnum.WORKREPORT_DAILY.getCode())){
                type = 1;
            } else if (Objects.equals(businessType,XbbRefTypeEnum.WORKREPORT_WEEKLY.getCode())){
                type = 2;
            } else if (Objects.equals(businessType,XbbRefTypeEnum.WORKREPORT_MONTHLY.getCode())){
                type = 3;
            }
            for(FieldAttrEntity entity : explainList) {
                if (Objects.equals(entity.getAttr(), WorkReportFieldEnum.TYPE.getAttr())) {
                    // 下拉不允许修改默认值，1不允许
                    entity.setItemBanDefault(BasicConstant.ONE);
                } else if(Objects.equals(entity.getAttr(),WorkReportFieldEnum.CC.getAttr())){
                    UserEntity userEntity = new UserEntity();
                    BeanUtil.copyProperties(formGetDTO.getLoginUser(),userEntity);
                    DefaultAttrPoJo defaultAttrPojo = workReportSetService.getCcUser(userEntity,type);
                    entity.setDefaultAttr(defaultAttrPojo);
                } else if (Objects.equals(entity.getAttr(),WorkReportFieldEnum.APPROVED_PEOPLE.getAttr())){
                    UserEntity userEntity = new UserEntity();
                    BeanUtil.copyProperties(formGetDTO.getLoginUser(),userEntity);
                    DefaultAttrPoJo defaultAttrPojo = workReportSetService.getApprovedPeople(userEntity,type);
                    entity.setDefaultAttr(defaultAttrPojo);
                }
            }
        } else if (Objects.equals(businessType, XbbRefTypeEnum.CONTRACT.getCode())) {
            for(FieldAttrEntity entity : explainList) {
                if (Objects.equals(entity.getAttr(), ContractEnum.EXPRESS_STATUS.getAttr())) {
                    // 发货状态可以添加选项值
                    entity.setDictionaryFlag(BasicConstant.ONE);
                } else if (Objects.equals(entity.getAttr(), ContractEnum.MINOR_USER.getAttr())) {
                    // 合同协同人可以设置必填
                    entity.setSetType(3);
                }
            }
        } else if (Objects.equals(businessType, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode())) {
            for(FieldAttrEntity entity : explainList) {
                if (Objects.equals(entity.getAttr(), CustomerManagementEnum.PHONE.getAttr())) {
                    if (Objects.isNull(entity.getShowPublicPool()) && Objects.isNull(entity.getPublicPool())) {
                        entity.setShowPublicPool(BasicConstant.ONE);
                        entity.setPublicPool(BasicConstant.ONE);
                    }
                    FormConfigEntity formConfigEntity = formConfigModel.getEntityByFormId(formGetDTO.getCorpid(), formGetDTO.getFormId(), FormConfigEnum.CUSTOMER_PHONE_REPEAT_TYPE.getConfig());
                    List<? extends FieldAttrEntity> items = entity.getSubForm().getItems();
                    for (FieldAttrEntity fieldAttrEntity  : items) {
                        if (Objects.equals(fieldAttrEntity.getAttr(), "text_2")) {
                            if (formConfigEntity != null) {
                                fieldAttrEntity.setCustomerPhoneRepeatType(Integer.valueOf(formConfigEntity.getConfigValue()));
                                // 后端维护下 noRepeat
                                if (Objects.equals(formConfigEntity.getConfigValue(), RepeatTypeEnum.REPEAT_CANCEL.getType().toString())) {
                                    fieldAttrEntity.setNoRepeat(RepeatTypeEnum.REPEAT_CANCEL.getType());
                                } else {
                                    fieldAttrEntity.setNoRepeat(RepeatTypeEnum.REPEAT_SINGLE.getType());
                                }
                            } else {
                                // 不存在就用 noRepeat 的值
                                fieldAttrEntity.setCustomerPhoneRepeatType(fieldAttrEntity.getNoRepeat());
                            }
                        }
                    }
                    break;
                }
                if(Objects.equals(entity.getAttr(), CustomerManagementEnum.CLUE_ID.getAttr())){
                    entity.setShowEditable(0);
                }
            }
            for(FieldAttrEntity entity : explainList) {
                if (Objects.equals(entity.getAttr(), CustomerManagementEnum.NAME.getAttr())) {
                    FormConfigEntity formConfigEntity = formConfigModel.getEntityByFormId(formGetDTO.getCorpid(), formGetDTO.getFormId(), FormConfigEnum.CUSTOMER_NAME_REPEAT_TYPE.getConfig());
                    if (formConfigEntity != null) {
                        entity.setCustomerNameRepeatType(Integer.valueOf(formConfigEntity.getConfigValue()));
                        // 后端维护下 noRepeat
                        if (Objects.equals(formConfigEntity.getConfigValue(), RepeatTypeEnum.REPEAT_CANCEL.getType().toString())) {
                            entity.setNoRepeat(RepeatTypeEnum.REPEAT_CANCEL.getType());
                        } else {
                            entity.setNoRepeat(RepeatTypeEnum.REPEAT_SINGLE.getType());
                        }
                    } else {
                        // 不存在就用 noRepeat 的值
                        entity.setCustomerNameRepeatType(entity.getNoRepeat());
                    }
                    break;
                }
            }

            //针对旗舰版
            if (Objects.equals(PackageTypeEnum.ULTIMATE.getType(), feeType)) {
                for(FieldAttrEntity entity : explainList) {
                    //兼容老数据，对自定义字段查重联合查重
                    if (Objects.equals(entity.getIsRedundant(), BasicConstant.ONE)) {
                        if (Objects.equals(entity.getFieldType(),FieldTypeEnum.SUB_FORM.getType())) {
                            if (Objects.nonNull(entity.getSubForm()) && CollectionsUtil.isNotEmpty(entity.getSubForm().getItems())) {
                                List<FieldAttrEntity> items = (List<FieldAttrEntity>) entity.getSubForm().getItems();
                                items.forEach(item -> {
                                    if (Objects.nonNull(item.getNoRepeat()) && Objects.equals(item.getNoRepeat(), BasicConstant.ONE) && Objects.isNull(item.getCustomRepeatType())) {
                                        item.setCustomRepeatType(BasicConstant.ONE);
                                        item.setCustomRecheckRules(new ArrayList<>());
                                    }
                                });
                            }
                        }
                        if (Objects.equals(entity.getFieldType(),FieldTypeEnum.TEXT.getType())) {
                            if (Objects.nonNull(entity.getNoRepeat()) && Objects.equals(entity.getNoRepeat(),BasicConstant.ONE) && Objects.isNull(entity.getCustomRepeatType()) ) {
                                entity.setCustomRepeatType(BasicConstant.ONE);
                                entity.setCustomRecheckRules(new ArrayList<>());
                            }
                        }
                    }
                }
            }

            //旗舰版用户降低到其他版本，所属公海字段是允许用户进行未启用操作的
            if (!Objects.equals(PackageTypeEnum.ULTIMATE.getType(), feeType)) {
                for(FieldAttrEntity entity : explainList) {
                    if (Objects.equals(entity.getAttr(), CustomerManagementEnum.PUBLIC_GROUP.getAttr())){
                        if(Objects.equals(entity.getIsOpen(), BasicConstant.ONE) && Objects.equals(entity.getIsForbidden(), BasicConstant.ZERO)) {
                            entity.setIsForbidden(BasicConstant.ONE);
                        }else if (Objects.equals(entity.getIsOpen(), BasicConstant.ZERO) && Objects.equals(entity.getIsForbidden(), BasicConstant.ONE)) {
                            entity.setIsForbidden(BasicConstant.ZERO);
                        }
                        break;
                    }
                }
            }
        } else if (Objects.equals(businessType, XbbRefTypeEnum.CONTACT.getCode())) {
            for(FieldAttrEntity entity : explainList) {
                if (Objects.equals(entity.getAttr(), ContactEnum.PHONE.getAttr())) {
                    if (Objects.isNull(entity.getShowPublicPool()) && Objects.isNull(entity.getPublicPool())) {
                        entity.setShowPublicPool(BasicConstant.ONE);
                        entity.setPublicPool(BasicConstant.ONE);
                    }
                    break;
                }
            }
        } else if (Objects.equals(businessType, XbbRefTypeEnum.DISTRIBUTOR_MANAGEMENT.getCode())) {
            for(FieldAttrEntity entity : explainList) {
                if (Objects.equals(entity.getAttr(), DistributorEnum.SCALE.getAttr())) {
                    List<ItemPoJo> items = entity.getItems();
                    for (ItemPoJo item : items) {
                        item.setNoDel(1);
                    }
                    break;
                }
            }
        } else if (Objects.equals(businessType, XbbRefTypeEnum.PAYMENT_SHEET.getCode())) {
            formatPaymentSheetExplain(formGetDTO, explainList);
        } else if (Objects.equals(businessType, XbbRefTypeEnum.PAY_SHEET.getCode())) {
            formatPaySheetExplain(formGetDTO, explainList);
        } else if (Objects.equals(businessType, XbbRefTypeEnum.CUSTOMER_COMMUNICATE.getCode())) {
            for(FieldAttrEntity entity : explainList) {
                if (Objects.equals(entity.getAttr(), CustomerCommunicateEnum.TYPE.getAttr())) {
                    List<ItemPoJo> items = entity.getItems();
                    Boolean needAddItem = true;
                    for (ItemPoJo itemPoJo : items) {
                        if (Objects.equals(itemPoJo.getValue().toString(), CommunicateTypeEnum.TELEPHONE_CALL.getCode())) {
                            needAddItem = false;
                            itemPoJo.setNoDel(BasicConstant.ONE);
                        }
                    }
                    if (needAddItem) {
                        ItemPoJo itemPoJo = new ItemPoJo();
                        itemPoJo.setNoDel(BasicConstant.ONE);
                        itemPoJo.setText(CommunicateTypeEnum.TELEPHONE_CALL.getName());
                        itemPoJo.setValue(CommunicateTypeEnum.TELEPHONE_CALL.getCode());

                        items.add(itemPoJo);
                    }
                    break;
                }
            }
        } else if (Objects.equals(businessType, XbbRefTypeEnum.PRODUCT.getCode())) {
            FilterAttrOnOffJXCDTO filterAttrOnOffJXCDTO = new FilterAttrOnOffJXCDTO();
            BeanUtil.copyProperties(formGetDTO, filterAttrOnOffJXCDTO);
            filterAttrOnOffJXCDTO.setOperatePageCode(OperatePageEnum.DESIGN.getCode());
            filterAttrOnOffJXCDTO.setFieldAttrEntityList(explainList);
            filterAttrOnOffJXCDTO.setEnableJxc(enableJxc);
            productModel.filterAttrOnOffJXC(filterAttrOnOffJXCDTO);
        } else if (Objects.equals(businessType, XbbRefTypeEnum.REFUND.getCode())) {
            FilterAttrOnOffJXCDTO filterAttrOnOffJXCDTO = new FilterAttrOnOffJXCDTO();
            BeanUtil.copyProperties(formGetDTO, filterAttrOnOffJXCDTO);
            filterAttrOnOffJXCDTO.setOperatePageCode(OperatePageEnum.DESIGN.getCode());
            filterAttrOnOffJXCDTO.setFieldAttrEntityList(explainList);
            filterAttrOnOffJXCDTO.setEnableJxc(enableJxc);
            refundModel.filterAttrOnOffJXC(filterAttrOnOffJXCDTO);
        } else if (Objects.equals(businessType, XbbRefTypeEnum.CLUE.getCode())) {
            for(FieldAttrEntity entity : explainList) {
                if (Objects.equals(entity.getAttr(), ClueEnum.COMPANY_NAME.getAttr())) {
                    FormConfigEntity formConfigEntity = formConfigModel.getEntityByFormId(formGetDTO.getCorpid(), formGetDTO.getFormId(), FormConfigEnum.CLUE_NAME_REPEAT_TYPE.getConfig());
                    if (formConfigEntity != null) {
                        entity.setCustomerNameRepeatType(Integer.valueOf(formConfigEntity.getConfigValue()));
                        // 后端维护下 noRepeat
                        if (Objects.equals(formConfigEntity.getConfigValue(), RepeatTypeEnum.REPEAT_CANCEL.getType().toString())) {
                            entity.setNoRepeat(RepeatTypeEnum.REPEAT_CANCEL.getType());
                        } else {
                            entity.setNoRepeat(RepeatTypeEnum.REPEAT_SINGLE.getType());
                        }
                    } else {
                        // 不存在就用 noRepeat 的值
                        entity.setCustomerNameRepeatType(entity.getNoRepeat());
                    }
                } else if (Objects.equals(entity.getAttr(), ClueEnum.PHONE.getAttr())) {
                    FormConfigEntity formConfigEntity = formConfigModel.getEntityByFormId(formGetDTO.getCorpid(), formGetDTO.getFormId(), FormConfigEnum.CLUE_PHONE_REPEAT_TYPE.getConfig());
                    List<? extends FieldAttrEntity> items = entity.getSubForm().getItems();
                    for (FieldAttrEntity fieldAttrEntity  : items) {
                        if (Objects.equals(fieldAttrEntity.getAttr(), "text_2")) {
                            if (formConfigEntity != null) {
                                fieldAttrEntity.setCustomerPhoneRepeatType(Integer.valueOf(formConfigEntity.getConfigValue()));
                                // 后端维护下 noRepeat
                                if (Objects.equals(formConfigEntity.getConfigValue(), RepeatTypeEnum.REPEAT_CANCEL.getType().toString())) {
                                    fieldAttrEntity.setNoRepeat(RepeatTypeEnum.REPEAT_CANCEL.getType());
                                } else {
                                    fieldAttrEntity.setNoRepeat(RepeatTypeEnum.REPEAT_SINGLE.getType());
                                }
                            } else {
                                // 不存在就用 noRepeat 的值
                                fieldAttrEntity.setCustomerPhoneRepeatType(fieldAttrEntity.getNoRepeat());
                            }
                        }
                    }
                }

                //兼容老数据，对自定义字段查重联合查重
                if (Objects.equals(PackageTypeEnum.ULTIMATE.getType(), feeType)) {
                    if (Objects.equals(entity.getIsRedundant(), BasicConstant.ONE) &&
                            (Objects.equals(entity.getFieldType(),FieldTypeEnum.TEXT.getType()) || Objects.equals(entity.getFieldType(),FieldTypeEnum.SUB_FORM.getType()))) {

                        if (Objects.equals(entity.getFieldType(),FieldTypeEnum.SUB_FORM.getType())) {
                            if (Objects.nonNull(entity.getSubForm()) && CollectionsUtil.isNotEmpty(entity.getSubForm().getItems())) {
                                List<FieldAttrEntity> items = (List<FieldAttrEntity>) entity.getSubForm().getItems();
                                items.forEach(item -> {
                                    if (Objects.nonNull(item.getNoRepeat()) && Objects.equals(item.getNoRepeat(), BasicConstant.ONE) && Objects.isNull(item.getCustomRepeatType())) {
                                        item.setCustomRepeatType(BasicConstant.ONE);
                                        item.setCustomRecheckRules(new ArrayList<>());
                                    }
                                });
                            }
                        } else {
                            if (Objects.nonNull(entity.getNoRepeat()) && Objects.equals(entity.getNoRepeat(),BasicConstant.ONE) && Objects.isNull(entity.getCustomRepeatType()) ) {
                                entity.setCustomRepeatType(BasicConstant.ONE);
                                entity.setCustomRecheckRules(new ArrayList<>());
                            }
                        }
                    }
                }
                //旗舰版用户降低到其他版本，所属公海字段是允许用户进行未启用操作的
                if (!Objects.equals(PackageTypeEnum.ULTIMATE.getType(), feeType)) {
                    if (Objects.equals(entity.getAttr(), ClueEnum.PUBLIC_GROUP.getAttr())){
                        if(Objects.equals(entity.getIsOpen(), BasicConstant.ONE) && Objects.equals(entity.getIsForbidden(), BasicConstant.ZERO)) {
                            entity.setIsForbidden(BasicConstant.ONE);
                        } else if (Objects.equals(entity.getIsOpen(), BasicConstant.ZERO) && Objects.equals(entity.getIsForbidden(), BasicConstant.ONE)) {
                            entity.setIsForbidden(BasicConstant.ZERO);
                        }
                    }
                }
            }
        } else if(Objects.equals(businessType, XbbRefTypeEnum.SALES_OPPORTUNITY.getCode())){
            for(FieldAttrEntity entity : explainList) {
                //旗舰版用户降低到其他版本，所属公海字段是允许用户进行未启用操作的
                if (!Objects.equals(PackageTypeEnum.ULTIMATE.getType(), feeType)) {
                    if (Objects.equals(entity.getAttr(), SalesOpportunityEnum.WIN_COMPETITOR.getAttr()) || Objects.equals(entity.getAttr(), SalesOpportunityEnum.LINK_COMPETITOR.getAttr())){
                        if(Objects.equals(entity.getIsOpen(), BasicConstant.ONE)) {
                            entity.setIsForbidden(BasicConstant.ONE);
                        } else if (Objects.equals(entity.getIsOpen(), BasicConstant.ZERO)) {
                            entity.setIsForbidden(BasicConstant.ZERO);
                        }
                    }
                }
            }
            for(FieldAttrEntity entity : explainList) {
                if (Objects.equals(entity.getAttr(), SalesOpportunityEnum.NAME.getAttr())) {
                    RecheckingRuleEntity ruleEntity = recheckingRuleModel.getRuleListByFormId(formGetDTO.getCorpid(), formGetDTO.getFormId(), businessType);
                    //获取新建不允许重复规则
                    List<RecheckFormRulePojo> noRepeatRuleList = JSONArray.parseArray(ruleEntity.getNoRepeatRule(), RecheckFormRulePojo.class);
                    if(CollectionsUtil.isNotEmpty(noRepeatRuleList)){
                        for (RecheckFormRulePojo recheckFormRulePojo : noRepeatRuleList) {
                            List<RecheckAttrRulePojo> opportunityRule = recheckFormRulePojo.getOpportunity();
                            if(CollectionsUtil.isNotEmpty(opportunityRule) && Objects.equals(opportunityRule.get(0).getAttr(),entity.getAttr())){
                                //是否全局判重
                                boolean isAll = Objects.equals(opportunityRule.get(0).getIsAll(),BasicConstant.ONE);
                                if(isAll){
                                    entity.setCustomerNameRepeatType(RepeatTypeEnum.REPEAT_ALL.getType());
                                }else {
                                    //仅模板内判重
                                    entity.setCustomerNameRepeatType(RepeatTypeEnum.REPEAT_SINGLE.getType());
                                }
                                //新建不允许重复勾选
                                entity.setNoRepeat(BasicConstant.ONE);
                            }else {
                                //新建不允许重复不勾选
                                entity.setNoRepeat(BasicConstant.ZERO);
                                entity.setCustomerNameRepeatType(RepeatTypeEnum.REPEAT_CANCEL.getType());
                            }
                        }
                    }
                    break;
                }
            }
        }else if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER_V2.getCode())){
            formatWorkOrderV2Explain(formGetDTO, explainList);
        }
    }

    /**
     * 同步更新表单模板中客户名称和客户电话的查重配置
     * @param formUpdateDTO
     * @param explainList
     * @param businessType
     * @author xingxing.xiao
     * @date 2019/11/13 11:07
     */
    private void syncCustomerRepeatType(FormUpdateDTO formUpdateDTO, List<FieldAttrEntity> explainList, String formName, Integer businessType) throws XbbException {
        String nameRepeatConfig = FormConfigEnum.CUSTOMER_NAME_REPEAT_TYPE.getConfig();
        String phoneRepeatConfig = FormConfigEnum.CUSTOMER_PHONE_REPEAT_TYPE.getConfig();
        String nameAttr = CustomerManagementEnum.NAME.getAttr();
        String phoneAttr = CustomerManagementEnum.PHONE.getAttr();
        String nameAttrName = CustomerManagementEnum.NAME.getAttrName();
        String phoneAttrName = CustomerManagementEnum.PHONE.getAttrName();
        if (Objects.equals(businessType, XbbRefTypeEnum.CLUE.getCode())) {
            nameRepeatConfig = FormConfigEnum.CLUE_NAME_REPEAT_TYPE.getConfig();
            phoneRepeatConfig = FormConfigEnum.CLUE_PHONE_REPEAT_TYPE.getConfig();
            nameAttr = ClueEnum.COMPANY_NAME.getAttr();
            phoneAttr = ClueEnum.PHONE.getAttr();
            nameAttrName = ClueEnum.COMPANY_NAME.getAttrName();
            phoneAttrName = ClueEnum.PHONE.getAttrName();
        }
        String corpid = formUpdateDTO.getCorpid();
        Long formId = formUpdateDTO.getFormId();
        for(FieldAttrEntity entity : explainList) {
            if (Objects.equals(entity.getAttr(), nameAttr)) {
                FormConfigEntity formConfigEntity = formConfigModel.getEntityByFormId(corpid, formId, nameRepeatConfig);
                if (formConfigEntity == null) {
                    // 若是第一次设置全局，将其余表单配置同步到表单配置表
                    if (Objects.equals(entity.getCustomerNameRepeatType(), RepeatTypeEnum.REPEAT_ALL.getType())) {
                        insertRepeatType(corpid, formUpdateDTO.getMenuId(), nameRepeatConfig, businessType);
                        // 加上日志
                        String userName = formUpdateDTO.getLoginUserName();
                        String userId = formUpdateDTO.getUserId();
                        String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_UPDATE_FORM_REPEAT), userName, formName, nameAttrName, RepeatTypeEnum.REPEAT_ALL.getMemo());
                        mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.PAAS_FORM, OperateTypeEnum.EDIT, formUpdateDTO.getFormId().toString(), formName, memo, formUpdateDTO.getHttpHeader());
                    }
                } else {
                    // 数据更改后才做后续判断
                    Integer nameRepeatType = entity.getCustomerNameRepeatType();
                    if (!Objects.equals(nameRepeatType.toString(), formConfigEntity.getConfigValue())) {
                        // 1. 从不判重或模板内判重改为全局判重(即现在是全局状态)，同步更改其他表单
                        // 2. 从全局判重改为不判重或模板内判重(即以前是全局状态)，同步更改其他表单
                        if (Objects.equals(nameRepeatType, RepeatTypeEnum.REPEAT_ALL.getType()) || Objects.equals(formConfigEntity.getConfigValue(), RepeatTypeEnum.REPEAT_ALL.getType().toString())) {
                            updateAllRepeatType(formUpdateDTO, nameRepeatConfig, nameRepeatType.toString());
                        } else {
                            // 3. 其余情况只更改自己
                            formConfigEntity.setConfigValue(nameRepeatType.toString());
                            formConfigEntity.setUpdateTime(DateTimeUtil.getInt());
                            try {
                                formConfigModel.update(formConfigEntity);
                            } catch (Exception e) {
                                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
                            }
                        }
                        // 加上日志
                        RepeatTypeEnum repeatTypeEnum = RepeatTypeEnum.getByType(nameRepeatType);
                        String userName = formUpdateDTO.getLoginUserName();
                        String userId = formUpdateDTO.getUserId();
                        String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_UPDATE_FORM_REPEAT), userName, formName, nameAttrName, I18nMessageUtil.getMessage(repeatTypeEnum.getMemo()));
                        mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.PAAS_FORM, OperateTypeEnum.EDIT, formUpdateDTO.getFormId().toString(), formName, memo, formUpdateDTO.getHttpHeader());
                    }
                }
                break;
            }
        }
        for(FieldAttrEntity entity : explainList) {
            if (Objects.equals(entity.getAttr(), phoneAttr)) {
                FormConfigEntity formConfigEntity = formConfigModel.getEntityByFormId(corpid, formId, phoneRepeatConfig);
                List<? extends FieldAttrEntity> items = entity.getSubForm().getItems();
                for (FieldAttrEntity item : items) {
                    if (Objects.equals(item.getAttr(), "text_2")) {
                        String phoneRepeatType = item.getCustomerPhoneRepeatType().toString();
                        if (formConfigEntity == null) {
                            // 若是第一次设置全局，将所有客户表单配置同步到表单配置表
                            if (Objects.equals(phoneRepeatType, RepeatTypeEnum.REPEAT_ALL.getType().toString())) {
                                insertRepeatType(corpid, formUpdateDTO.getMenuId(), phoneRepeatConfig, businessType);
                                // 加上日志
                                String userName = formUpdateDTO.getLoginUserName();
                                String userId = formUpdateDTO.getUserId();
                                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_UPDATE_FORM_REPEAT), userName, formName, phoneAttrName, RepeatTypeEnum.REPEAT_ALL.getMemo());
                                mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.PAAS_FORM, OperateTypeEnum.EDIT, formUpdateDTO.getFormId().toString(), formName, memo, formUpdateDTO.getHttpHeader());
                            }
                        } else {
                            if (!Objects.equals(phoneRepeatType, formConfigEntity.getConfigValue())) {
                                // 1. 从不判重或模板内判重改为全局判重(即现在是全局状态)，同步更改其他表单
                                // 2. 从全局判重改为不判重或模板内判重(即以前是全局状态)，同步更改其他表单
                                if (Objects.equals(phoneRepeatType, RepeatTypeEnum.REPEAT_ALL.getType().toString()) || Objects.equals(formConfigEntity.getConfigValue(), RepeatTypeEnum.REPEAT_ALL.getType().toString())) {
                                    updateAllRepeatType(formUpdateDTO, phoneRepeatConfig, phoneRepeatType);
                                } else {
                                    // 3. 其余情况只更改自己
                                    formConfigEntity.setConfigValue(phoneRepeatType);
                                    formConfigEntity.setUpdateTime(DateTimeUtil.getInt());
                                    try {
                                        formConfigModel.update(formConfigEntity);
                                    } catch (Exception e) {
                                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
                                    }
                                }
                                // 加上日志
                                RepeatTypeEnum repeatTypeEnum = RepeatTypeEnum.getByType(Integer.valueOf(phoneRepeatType));
                                String userName = formUpdateDTO.getLoginUserName();
                                String userId = formUpdateDTO.getUserId();
                                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_UPDATE_FORM_REPEAT), userName, formName, phoneAttrName, I18nMessageUtil.getMessage(repeatTypeEnum.getMemo()));
                                mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.PAAS_FORM, OperateTypeEnum.EDIT, formUpdateDTO.getFormId().toString(), formName, memo, formUpdateDTO.getHttpHeader());
                            }
                        }
                    }
                }
                break;
            }
        }
    }

    /**
     * 所有客户表单配置同步到表单配置表
     * @param corpid
     * @param menuId
     * @param config
     * @author xingxing.xiao
     * @date 2019/11/13 16:47
     */
    private void insertRepeatType (String corpid, Long menuId, String config, Integer businessType) {
        // 查出 formId 插入 tb_form_config 表
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("columns", "id");
        param.put("corpid", corpid);
        param.put("menuId", menuId);
        param.put("del", 0);
        List<PaasFormEntityExt> formEntitys = paasFormModel.getByBusinessTypes(param);
        List<FormConfigEntity> formConfigEntityList = new ArrayList<>();
        for (PaasFormEntityExt formEntity : formEntitys) {
            FormConfigEntity configEntity = new FormConfigEntity(corpid, formEntity.getId(), SaasMarkEnum.SAAS.getCode(), businessType, config, RepeatTypeEnum.REPEAT_ALL.getType().toString());
            formConfigEntityList.add(configEntity);
        }
        formConfigModel.insertBatch(formConfigEntityList);
    }

    /**
     * CRM 简化版表单配置
     * @param corpid
     * @param formGetVO
     * @author xingxing.xiao
     * @date 2019/11/29 14:41
     */
    private void getSimpleCRMFormSet(String corpid, FormGetVO formGetVO, boolean formAttrFlag, Integer businessType) throws XbbException {
        // 判断是否标准版(若不是标准版则不使用镜像)
        BasePackageInfoVO basePackageInfoVO = packageService.getBasePackageInfoFromRedis(corpid);
        if (!Objects.equals(basePackageInfoVO.getFeeType(), PackageTypeEnum.STANDARD.getType())) {
            formGetVO.setIsMirror(0);
            return;
        }

        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put("columns", "id, version_id, is_professional");
        params.put("corpid", corpid);
        params.put("del", 0);
        MirrorCompanyEntity mirrorCompany = mirrorCompanyModel.getMirrorCompany(params);
        if (mirrorCompany != null) {

            // 2. 若启用标准版则不再使用镜像
            if (Objects.equals(mirrorCompany.getIsProfessional(), 1)) {
                formGetVO.setIsMirror(0);
                return;
            }
            params.clear();
            params.put("columns", "info, module");
            params.put("versionId", mirrorCompany.getVersionId());
            params.put("moduleIn", Arrays.asList(MirrorModuleEnum.FORM_ATTR.getAlias(), MirrorModuleEnum.FIELD_ATTR.getAlias()));
            List<MirrorInfoEntity> infoList = mirrorInfoModel.findEntitys(params);
            for (MirrorInfoEntity entity : infoList) {
                if (Objects.equals(entity.getModule(), MirrorModuleEnum.FORM_ATTR.getAlias())) {
                    JSONObject jsonObject = JSONObject.parseObject(entity.getInfo());
                    FormSetVo formSetVo = JSONObject.parseObject(jsonObject.getString("formSet"), FormSetVo.class);
                    FormAttrSetVO formAttrSetVO = JSONObject.parseObject(jsonObject.getString("formAttrSet"), FormAttrSetVO.class);
                    if (Objects.equals(businessType, XbbRefTypeEnum.COMMUNICATE_PLAN.getCode())) {
                        // 访客计划特殊逻辑-延期原因
                        formAttrSetVO.setEnable(1);
                    } else {
                        formAttrSetVO.setEnable(formAttrFlag ? 1 : 0);
                    }
                    FormSimpleSetVO formSimpleSetVO = new FormSimpleSetVO();
                    formSimpleSetVO.setFormSet(formSetVo);
                    formSimpleSetVO.setFormAttrSet(formAttrSetVO);
                    formGetVO.setFormSimpleSet(formSimpleSetVO);
                } else if (Objects.equals(entity.getModule(), MirrorModuleEnum.FIELD_ATTR.getAlias())) {
                    FormExplainSimpleSetVo explainSet = JSONObject.parseObject(entity.getInfo(), FormExplainSimpleSetVo.class);
                    formGetVO.setFormExplainSet(explainSet);
                }
            }
            formGetVO.setIsMirror(1);
        } else {
            // 没使用镜像
            formGetVO.setIsMirror(0);
        }
    }

    /**
     * 更新表单配置
     * @param formUpdateDTO
     * @param config
     * @param repeatType
     * @author xingxing.xiao
     * @date 2019/11/11 09:59
     */
    private void updateAllRepeatType(FormUpdateDTO formUpdateDTO, String config, String repeatType) {
        String corpid = formUpdateDTO.getCorpid();
        // 最简单的方式是用 corpid 和 config 来匹配符合条件的表单配置（不然就是根据 menuId 查出下面所有的 formId，再更新所有表单的配置）
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("config", config);
        param.put("configValue", repeatType);
        param.put("updateTime", DateTimeUtil.getInt());
        formConfigModel.updateRepeatType(param);
    }

    /**
     * 处理回款单的字段解释list（主要处理预收款菜单关闭时，相应类型隐藏）
     * @param formGetDTO
     * @param explainList
     * @throws XbbException
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    private void formatPaymentSheetExplain(FormGetDTO formGetDTO, List<FieldAttrEntity> explainList) throws XbbException {
        //判断预收款菜单是否开启
        boolean prepaymentFlag = paasMenuService.enableMenu(formGetDTO.getCorpid(), XbbRefTypeEnum.PREPAYMENT_BALANCE.getAlias());
        for (FieldAttrEntity entity : explainList) {
            if (Objects.equals(entity.getAttr(), PaymentSheetEnum.PAYMENT_SHEET_TYPE.getAttr())) {
                //根据预收款是否开启，设置预收款相关类型的显隐
                List<ItemPoJo> itemPoJoList = dataDictionaryModel.getDictionaryList4PaymentSheetType(prepaymentFlag);
                entity.setItems(itemPoJoList);
            }
        }
    }
    /**
     * 处理付款单的字段解释list（主要处理预付款菜单关闭时，相应类型隐藏）
     * @param formGetDTO
     * @param explainList
     * @throws XbbException
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    private void formatPaySheetExplain(FormGetDTO formGetDTO, List<FieldAttrEntity> explainList) throws XbbException {
        //判断预付款菜单是否开启
        boolean prepayFlag = paasMenuService.enableMenu(formGetDTO.getCorpid(), XbbRefTypeEnum.PREPAY_BALANCE.getAlias());
        for (FieldAttrEntity entity : explainList) {
            if (Objects.equals(entity.getAttr(), PaySheetEnum.PAY_SHEET_TYPE.getAttr())) {
                //根据预付款是否开启，设置预付款相关类型的显隐
                List<ItemPoJo> itemPoJoList = dataDictionaryModel.getDictionaryList4PaySheetType(prepayFlag);
                entity.setItems(itemPoJoList);
            }
        }
    }

    // 处理工单特殊下拉选项
    private void formatWorkOrderV2Explain(FormGetDTO formGetDTO, List<FieldAttrEntity> explainList) throws XbbException {
        // 当前阶段
        // 来源工单池  查询所有工单池
        XbbResponse<WorkOrderV2ComboVO> xbbResponse = workOrderV2ComboFeignClient.getComboItem(formGetDTO, LocaleContextHolder.getLocale().toString());
        if (!xbbResponse.isSuccess()) {
            throw new XbbException(xbbResponse.getCode(), xbbResponse.getMsg());
        }
        WorkOrderV2ComboVO result = xbbResponse.getResult();
        List<ItemPoJo> currentPhaseItems = result.getCurrentPhaseItems();
        List<ItemPoJo> sourcePoolItems = result.getSourcePoolItems();
        for (FieldAttrEntity fieldAttrEntity : explainList) {
            if (Objects.equals("currentPhase",fieldAttrEntity.getSaasAttr())){
                fieldAttrEntity.setItems(currentPhaseItems);
                fieldAttrEntity.setItemBanDefault(1);
            }else if (Objects.equals("sourceCatalogue",fieldAttrEntity.getSaasAttr())){
                fieldAttrEntity.setItems(sourcePoolItems);
                fieldAttrEntity.setItemBanDefault(1);
            }
        }
    }

    /**
     * 查询单条数据，判断查询出来的configValue的状态码是1还是0，1则返回true,0则返回false
     * @param corpid
     * @param config
     * @param formId
     * @return
     * @throws XbbException
     */
    @Override
    public Boolean getSingleRuleList(String corpid, String config, Long formId) throws XbbException {
        return proFormHelp.getSingleRuleList(corpid, config, formId);
    }


    /**
     * 关联“设置更新规则”列表
     * @param formRuleListDTO
     * @return
     * @throws XbbException
     */
    @Override
    public FormRuleListVO getRuleList(FormRuleListDTO formRuleListDTO) throws XbbException {
        FormRuleListVO formRuleListVO = null;
        try {
            formRuleListVO = new FormRuleListVO();
            Long formId = formRuleListDTO.getFormId();
            String corpid = formRuleListDTO.getCorpid();
            Integer businessType = formRuleListDTO.getBusinessType();
            Integer saasMark = formRuleListDTO.getSaasMark();
            if (Objects.equals(formRuleListDTO.getBusinessType(), XbbRefTypeEnum.CLUE.getCode())) {
                List<String> associatedConfigs = ClueRuleSettingEnum.getAliasByType(XbbSetUpdateRuleEnum.ASSOCIATED_BUSINESS.getCode());
                formRuleListVO.setAssociatedBusinessList(clueRuleList(corpid,formId,businessType,saasMark,associatedConfigs));
                List<String> callConfigs = ClueRuleSettingEnum.getAliasByType(XbbSetUpdateRuleEnum.CALL_LOG.getCode());
                formRuleListVO.setCallLogList(clueRuleList(corpid,formId,businessType,saasMark,callConfigs));
                List<String> stageConfigs = ClueRuleSettingEnum.getAliasByType(XbbSetUpdateRuleEnum.CLUE_STAGE_LIST.getCode());
                formRuleListVO.setCustomerStageList(clueRuleList(corpid,formId,businessType,saasMark,stageConfigs));
                return formRuleListVO;
            }
            // ---------------下面是客户的---------
            //获取关联业务中的别名
            String newFollowUpRecordVisitingTime = RuleSettingEnum.NEW_FOLLOW_UP_RECORD_VISITING_TIME.getConfig();
            String newContractOrderCreateTime = RuleSettingEnum.NEW_CONTRACT_ORDER_CREATE_TIME.getConfig();
            String newOpportunitiesCreateTime = RuleSettingEnum.NEW_OPPORTUNITIES_CREATE_TIME.getConfig();
            String newSignInCheckInTime = RuleSettingEnum.NEW_SIGN_IN_CHECK_IN_TIME.getConfig();
            //获取通话记录中的别名
            String telephoneConnectionDialTime = RuleSettingEnum.TELEPHONE_CONNECTION_DIAL_TIME.getConfig();
            //获取客户阶段中的别名
            String stageJumpGoToTime = RuleSettingEnum.STAGE_JUMP_GO_TO_TIME.getConfig();
            String completePhaseWorkCompletionTime = RuleSettingEnum.COMPLETE_PHASE_WORK_COMPLETION_TIME.getConfig();
            String fillingInStageFeedbackCreateTime = RuleSettingEnum.FILLING_IN_STAGE_FEEDBACK_CREATE_TIME.getConfig();

            //关联业务
            List<String> associatedConfigList = new ArrayList<>();
            associatedConfigList.add(newFollowUpRecordVisitingTime);
            associatedConfigList.add(newContractOrderCreateTime);
            associatedConfigList.add(newOpportunitiesCreateTime);
            associatedConfigList.add(newSignInCheckInTime);
            formRuleListVO.setAssociatedBusinessList(ruleList(corpid,formId,businessType,saasMark,associatedConfigList));
            //通话记录
            List<String> callConfigList = new ArrayList<>();
            callConfigList.add(telephoneConnectionDialTime);
            formRuleListVO.setCallLogList(ruleList(corpid,formId, businessType, saasMark, callConfigList));
            //客户阶段
            List<String> customerConfigList = new ArrayList<>();
            customerConfigList.add(stageJumpGoToTime);
            customerConfigList.add(completePhaseWorkCompletionTime);
            customerConfigList.add(fillingInStageFeedbackCreateTime);
            formRuleListVO.setCustomerStageList(ruleList(corpid,formId, businessType, saasMark, customerConfigList));

        } catch (Exception e) {
            LOG.error("paasFormData数据库查询表单数据出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return formRuleListVO;
    }

    /**
     * 获取自定义字段关联查重字段
     * @param customRepeatLinkExplainDTO
     * @return
     * @throws XbbException
     */
    @Override
    public CustomRepeatLinkExplainGetVO customRepeatLinkExplain(CustomRepeatLinkExplainDTO customRepeatLinkExplainDTO) throws XbbException {
        CustomRepeatLinkExplainGetVO customRepeatLinkExplainGetVO = null;
        try {
            customRepeatLinkExplainGetVO = new CustomRepeatLinkExplainGetVO();
            List<CustomRepeatLinkExplainListPojo> customRepeatLinkExplainListPojos = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            String corpid = customRepeatLinkExplainDTO.getCorpid();
            Integer businessType = customRepeatLinkExplainDTO.getBusinessType();
            Long formId = customRepeatLinkExplainDTO.getFormId();
            Integer fieldType = customRepeatLinkExplainDTO.getFieldType();
            String attr = customRepeatLinkExplainDTO.getAttr();
            if (XbbRefTypeEnum.checkMutiFormRecheckBusinessType(businessType)) {
                List<PaasFormEntityExt> enableFormList = paasFormModel.getFormListDistributor(corpid, businessType, BasicConstant.ZERO);
                if (CollectionsUtil.isNotEmpty(enableFormList)) {
                    PaasFormExplainEntity currentExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
                    if (Objects.nonNull(currentExplainEntity)) {
                        FieldAttrEntity fieldAttrEntity = null;
                        //判断是否该字段是否已经有设置联合查重关系
                        Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(currentExplainEntity.getExplains());
                        if (attr.contains(StringConstant.POINT)) {
                            //说明是子表单中的单行文本
                            String[] attrSplit = attr.split("\\.");
                            if (attrSplit != null && attrSplit.length > 0) {
                                String preAttr = attrSplit[0];
                                String fixAttr = attrSplit[1];
                                FieldAttrEntity preFieldAttrEntity = explainMap.get(preAttr);
                                if (Objects.nonNull(preFieldAttrEntity) && Objects.nonNull(preFieldAttrEntity.getSubForm()) && CollectionsUtil.isNotEmpty(preFieldAttrEntity.getSubForm().getItems())) {
                                    List<FieldAttrEntity> items = (List<FieldAttrEntity>) preFieldAttrEntity.getSubForm().getItems();
                                    fieldAttrEntity = items.stream().filter(item -> Objects.equals(fixAttr, item.getAttr())).findAny().orElse(null);
                                }
                            } else {
                                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100015, SystemErrorCodeEnum.API_ERROR_100015.getMsg());
                            }
                        } else {
                            fieldAttrEntity = explainMap.get(attr);
                        }

                        List<CustomRecheckRulePojo> customRecheckRules = null;
                        if (Objects.nonNull(fieldAttrEntity)) {
                            customRecheckRules = fieldAttrEntity.getCustomRecheckRules();
                        }
                        for (PaasFormEntityExt paasFormEntityExt : enableFormList) {
                            if (!Objects.equals(paasFormEntityExt.getId(),formId)) {
                                CustomRepeatLinkExplainListPojo customRepeatLinkExplainListPojo = new CustomRepeatLinkExplainListPojo();
                                PaasFormExplainEntity explainEntity = paasFormExplainModel.getByFormId(paasFormEntityExt.getId(), corpid);
                                List<FieldAttrEntity> explainList =  JSONArray.parseArray(explainEntity.getExplains(), FieldAttrEntity.class);
                                List<CustomRepeatLinkExplainPojo> customRepeatLinkExplainPojos = handleRepeatLinkExplain(fieldType,explainList);
                                customRepeatLinkExplainListPojo.setAttrList(customRepeatLinkExplainPojos);
                                customRepeatLinkExplainListPojo.setFormId(paasFormEntityExt.getId());
                                customRepeatLinkExplainListPojo.setFormName(paasFormEntityExt.getName());
                                if (CollectionsUtil.isNotEmpty(customRecheckRules)) {
                                    CustomRecheckRulePojo customRecheckRulePojo = customRecheckRules.stream().filter(item -> Objects.equals(item.getFormId(), paasFormEntityExt.getId())).findAny().orElse(null);
                                    if (Objects.nonNull(customRecheckRulePojo)) {
                                        customRepeatLinkExplainListPojo.setCheckedAttr(customRecheckRulePojo.getAttr());
                                    } else {
                                        customRepeatLinkExplainListPojo.setCheckedAttr("");
                                    }
                                } else {
                                    customRepeatLinkExplainListPojo.setCheckedAttr("");
                                }
                                customRepeatLinkExplainListPojos.add(customRepeatLinkExplainListPojo);
                            }
                        }
                        customRepeatLinkExplainGetVO.setRepeatLinkAttr(customRepeatLinkExplainListPojos);
                    }
                }
            }
        } catch (Exception e) {
            LOG.error("customRepeatLinkExplain获取自定义字段关联查重字段出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return customRepeatLinkExplainGetVO;
    }

    private List<CustomRepeatLinkExplainPojo> handleRepeatLinkExplain(Integer fieldType, List<FieldAttrEntity> explainList)  throws XbbException {
        List<CustomRepeatLinkExplainPojo> customRepeatLinkExplainPojos;
        try {
            customRepeatLinkExplainPojos = new ArrayList<>();
            if (CollectionsUtil.isEmpty(explainList)){
                return customRepeatLinkExplainPojos;
            }
            for (FieldAttrEntity fieldAttrEntity : explainList) {
                CustomRepeatLinkExplainPojo customRepeatLinkExplainPojo = new CustomRepeatLinkExplainPojo();
                if (Objects.equals(fieldAttrEntity.getIsOpen(),BasicConstant.ONE) && Objects.equals(fieldAttrEntity.getIsRedundant(), BasicConstant.ONE)) {
                    //关联和被关联的字段类型必须一致
                    boolean isTextOrSerialNo = (Objects.equals(fieldType, FieldTypeEnum.TEXT.getType()) && Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.TEXT.getType()))
                            || (Objects.equals(fieldType, FieldTypeEnum.SERIALNO.getType()) && Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.SERIALNO.getType()));
                    if (isTextOrSerialNo) {
                        //关联查重字段类型为单行文本和流水号
                        customRepeatLinkExplainPojo.setFieldId(fieldAttrEntity.getFieldId());
                        customRepeatLinkExplainPojo.setAttr(fieldAttrEntity.getAttr());
                        customRepeatLinkExplainPojo.setAttrName(fieldAttrEntity.getAttrName());
                        customRepeatLinkExplainPojos.add(customRepeatLinkExplainPojo);
                    }
                    boolean isSubText = Objects.equals(fieldType, FieldTypeEnum.TEXT.getType()) && Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.SUB_FORM.getType());
                    //还需要考虑子表单中的单行文本
                    if (isSubText) {
                        SubFormPoJo subForm = fieldAttrEntity.getSubForm();
                        if (Objects.nonNull(subForm) && CollectionsUtil.isNotEmpty(subForm.getItems())) {
                            List<? extends FieldAttrEntity> items = subForm.getItems();
                            for (FieldAttrEntity item : items) {
                                if (Objects.equals(item.getIsOpen(), BasicConstant.ONE) && Objects.equals(item.getFieldType(), FieldTypeEnum.TEXT.getType())) {
                                    CustomRepeatLinkExplainPojo subCustomRepeatLinkExplainPojo = new CustomRepeatLinkExplainPojo();
                                    subCustomRepeatLinkExplainPojo.setFieldId(item.getFieldId());
                                    subCustomRepeatLinkExplainPojo.setAttr(fieldAttrEntity.getAttr() + StringConstant.POINT + item.getAttr());
                                    subCustomRepeatLinkExplainPojo.setAttrName(fieldAttrEntity.getAttrName() + StringConstant.POINT + item.getAttrName());
                                    customRepeatLinkExplainPojos.add(subCustomRepeatLinkExplainPojo);
                                }
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            LOG.error("handleRepeatLinkExplain解析处理自定义关联查重字段失败", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return customRepeatLinkExplainPojos;
    }

    /**
     * 查询更新规则
     * @param corpid
     * @param formId
     * @param businessType
     * @param saasMark
     * @param configList
     * @return
     */
    private List<FormConfigEntity> ruleList(String corpid, Long formId, Integer businessType, Integer saasMark, List<String> configList) throws  XbbException{
        SignInSetEntity entity;
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid",corpid);
        param.put("del", DelEnum.NORMAL.getDel());
        List<SignInSetEntity> signInSetEntityList = signInSetModel.findEntitys(param);
        if (CollectionsUtil.isEmpty(signInSetEntityList)) {
            return new ArrayList<>();
        }
        entity = signInSetEntityList.get(0);

        List<FormConfigEntity> formConfigEntity = formConfigModel.getButtonEntityByFormId(corpid, formId, configList);
        Map<String, FormConfigEntity> formConfigEntityMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (FormConfigEntity configEntity : formConfigEntity) {
            formConfigEntityMap.put(configEntity.getConfig(), configEntity);
        }

        List<FormConfigEntity> formConfigEntityList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (String str : configList) {
            FormConfigEntity configEntity = formConfigEntityMap.get(str);
            RuleSettingEnum ruleSettingEnum = RuleSettingEnum.getByConfig(str);
            if (Objects.isNull(configEntity)) {
                configEntity = new FormConfigEntity();
                configEntity.setCorpid(corpid);
                configEntity.setFormId(formId);
                configEntity.setSaasMark(saasMark);
                configEntity.setBusinessType(businessType);
                configEntity.setConfig(ruleSettingEnum.getConfig());
                configEntity.setConfigValue(ruleSettingEnum.getConfigValue());
            }
            configEntity.setFormName(ruleSettingEnum.getName());
            if (Objects.equals(configEntity.getConfig(), RuleSettingEnum.NEW_SIGN_IN_CHECK_IN_TIME.getConfig()) && Objects.equals(entity.getIfFollowRecords(), 0)) {
                configEntity.setIsDisabled(true);
            }
            formConfigEntityList.add(configEntity);
        }
        return formConfigEntityList;
    }

    /**
     * 查询更新规则
     * @param corpid
     * @param formId
     * @param businessType
     * @param saasMark
     * @param configList
     * @return
     */
    private List clueRuleList(String corpid, Long formId, Integer businessType, Integer saasMark, List<String> configList) throws  XbbException{
        List<FormConfigEntity> formConfigEntity = formConfigModel.getButtonEntityByFormId(corpid, formId, configList);
        Map<String, FormConfigEntity> formConfigEntityMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (FormConfigEntity configEntity : formConfigEntity) {
            formConfigEntityMap.put(configEntity.getConfig(), configEntity);
        }

        List<FormConfigEntity> formConfigEntityList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (String str : configList) {
            FormConfigEntity configEntity = formConfigEntityMap.get(str);
            ClueRuleSettingEnum ruleSettingEnum = ClueRuleSettingEnum.getByConfig(str);
            if (Objects.isNull(configEntity)) {
                configEntity = new FormConfigEntity();
                configEntity.setCorpid(corpid);
                configEntity.setFormId(formId);
                configEntity.setSaasMark(saasMark);
                configEntity.setBusinessType(businessType);
                configEntity.setConfig(ruleSettingEnum.getConfig());
                configEntity.setConfigValue(ruleSettingEnum.getConfigValue());
            }
            configEntity.setFormName(ruleSettingEnum.getName());
            formConfigEntityList.add(configEntity);
        }
        return formConfigEntityList;
    }

    /**
     * 获取使用权限列表
     * @param paasFormEntityExt
     * @return
     * 创建时间 2019/6/8 2:00 PM
     * 修改时间 2019/6/8 2:00 PM
     */
    private List<OptionalRangeEntity> getPermissions(PaasFormEntityExt paasFormEntityExt) {
        String permissionStr = paasFormEntityExt.getPermission();
        List<OptionalRangeEntity> permissions = null;

        try {
            permissions = JSON.parseArray(permissionStr, OptionalRangeEntity.class);
        } catch (Exception e) {

        }

        if (permissions == null) {
            permissions = new ArrayList<>();
        }
        return permissions;
    }
    /**
     * 校验es字段长度限制
     * @param fieldTypeEnum
     * @param proEsAliasEnum
     * @param esAliasLength
     * @param isReviewer
     * @param name
     * @return void
     * @author 吴峰
     * @date 2020/9/25 17:09
     * @throws XbbException
     */
    private void validateEsAliasLength(FieldTypeEnum fieldTypeEnum, ProEsAliasEnum proEsAliasEnum, Integer esAliasLength, boolean isReviewer, String name) throws XbbException {
        switch (fieldTypeEnum) {
            case TEXT:
            case TEXTAREA:
            case COMBO:
            case USER:
            case DEPT:
            case RADIO_GROUP:
            case BIRTHDAY:
            case MEMO:
            case LINK_DATA:
            case LINK_BUSINESS_SINGLE:
            case LINK_BUSINESS_MULTI:
            case CHECK_COMBO:
            case COMBO_LINK_BUSINESS:
            case SPECIFICATION:
            case TEXT_CHECK:
            case RICH_TEXT_EDITOR:
            case LINK_BUSINESS_COMBO:
            case WORK_ORDER_TIME_OUT:
            case WORK_ORDER_DATA_TIME_OUT:
            case WORK_ORDER_STAGE_NAME:
                if (isReviewer) {
                    // 工作报告的特殊逻辑
                    validateFieldEsAliasLength(esAliasLength, proEsAliasEnum.getArrayMax(), name);
                } else {
                    validateFieldEsAliasLength(esAliasLength, proEsAliasEnum.getTextMax(), name);
                }
                break;
            case NUM:
            case COMBO_NUM:
            case STAR:
            case SWITCH:
            case CATEGORY_ID:
            case WORK_ORDER_STATUS:
            case WORK_ORDER_STAGE:
            case WORK_ORDER_ALL_OUTBOUND:
            case WORK_ORDER_NODE_STATUS:
                validateFieldEsAliasLength(esAliasLength, proEsAliasEnum.getNumMax(), name);
                break;
            case LONG:
                validateFieldEsAliasLength(esAliasLength, proEsAliasEnum.getLongMax(), name);
                break;
            case ADDRESS:
                validateFieldEsAliasLength(esAliasLength, proEsAliasEnum.getAddressMax(), name);
                break;
            case LOCATION:
                validateFieldEsAliasLength(esAliasLength, proEsAliasEnum.getGeoMax(), name);
                break;
            case DATETIME:
            case ENDTIME:
            case CLOSETIME:
                validateFieldEsAliasLength(esAliasLength, proEsAliasEnum.getDateMax(), name);
                break;
            case SUB_FORM:
            case CONTACT_NUMBER:
            case SINGLE_SUB_FORM:
            case SWITCH_TEXT:
                validateFieldEsAliasLength(esAliasLength, proEsAliasEnum.getSubFormMax(), name);
                break;
            case UPLOAD:
            case VIDEO:
            case HREF:
                validateFieldEsAliasLength(esAliasLength, proEsAliasEnum.getFileMax(), name);
                break;
            case COMBO_CHECK:
            case CHECKBOX_GROUP:
            case USER_GROUP:
            case DEPT_GROUP:
            case SELECT_PRODUCT:
            case LINK_FORM:
            case CASCADER:
            case BATCH:
                validateFieldEsAliasLength(esAliasLength, proEsAliasEnum.getArrayMax(), name);
                break;
            case SEPARATOR:
                validateFieldEsAliasLength(esAliasLength, proEsAliasEnum.getOtherMax(), name);
                break;
            default:
                break;
        }
    }
    /**
     * 校验es字段长度限制
     * @param fieldEsAliasLength
     * @param esAliasMaxLength
     * @param name
     * @return void
     * @author 吴峰
     * @date 2020/9/25 17:09
     * @throws XbbException
     */
    private void validateFieldEsAliasLength(Integer fieldEsAliasLength , Integer esAliasMaxLength, String name) throws XbbException {
        if (fieldEsAliasLength > esAliasMaxLength)  {
            throw new XbbException(ProErrorCodeEnum.API_ERROR_260021, ProErrorCodeEnum.API_ERROR_260021.getMsg(), name);
        }
    }

    private void validateFieldEsAlias(String attrAlias, String esAlias, boolean isReviewer, String name) throws XbbException {
        if (!Objects.equals(attrAlias, esAlias) && !isReviewer)  {
            throw new XbbException(ProErrorCodeEnum.API_ERROR_260022, ProErrorCodeEnum.API_ERROR_260022.getMsg(), name);
        }
    }

    private void deleteOtherByDeleteForm(Long formId, String corpid , Integer businessType) throws XbbException {
        try {
            // 删除表单时，需要判断该表单是否被关联列表设置
            associationService.updateAssociation(corpid, formId, businessType);
            // 删掉流程相关的东西
            paasProcessTemplateModel.deleteByFormId(formId, corpid);
            paasProcessTemplateNodeModel.deleteByFormId(formId, corpid);
            paasProcessTaskModel.deleteByFormId(formId, corpid);
            paasProcessNodeTaskModel.deleteByFormId(formId, corpid);
            paasProcessDataModel.deleteByFormId(formId, corpid);
            businessRuleInfoModel.deleteByForm(formId, businessType, corpid);

            customButtonModel.deleteByFormId(formId, corpid, businessType);
            customButtonActionModel.deleteFormId(formId, corpid, businessType);
            paasFormServiceModel.deleteByFormId(formId, corpid, businessType);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("PaasFormServiceImpl.deleteOtherByDeleteForm  出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }

    }

    @Override
    public UpdateExplainStageVO updateExplainStage(UpdateExplainStageDTO updateExplainStageDTO) throws XbbException {
        String corpid = updateExplainStageDTO.getCorpid();
        Long formId = updateExplainStageDTO.getFormId();
        Integer saasMark = updateExplainStageDTO.getSaasMark();
        Integer businessType = updateExplainStageDTO.getBusinessType();
        StageProcessEntity stageProcessEntity;
        if (Objects.isNull(updateExplainStageDTO.getStageProcessId())) {
            stageProcessEntity = stageProcessModel.getEnableStageProcess(corpid, formId);
        } else {
            stageProcessEntity = stageProcessModel.getByKey(updateExplainStageDTO.getStageProcessId(), corpid);
        }
        //如果当前没有启用流程 返回空
        if (Objects.isNull(stageProcessEntity) || Objects.equals(stageProcessEntity.getDel(), DelEnum.DELETE.getDel()) || Objects.equals(stageProcessEntity.getEnable(), EnableEnum.CLOSE.getCode())) {
            UpdateExplainStageVO updateExplainStageVO = new UpdateExplainStageVO();
            updateExplainStageVO.setItems(new ArrayList<>());
            return updateExplainStageVO;
        }
        Long stageProcessId = stageProcessEntity.getId();
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put(ParameterConstant.CORPID, corpid);
        params.put(ParameterConstant.FORMID, formId);
        params.put(ParameterConstant.DEL, BasicConstant.ZERO);
        params.put(ParameterConstant.ENABLE, BasicConstant.ONE);
        params.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT + " " + SortOrder.DESC);
        params.put(ParameterConstant.STAGE_PROCESS_ID, stageProcessId);
        try {
            StageHandle stageHandle = stageHandleFactory.getStageHandle(saasMark, businessType);
            List<ItemPoJo> itemPoJos = stageHandle.getStageByStageProgress(params, formId, corpid);
            mendColor4Stage(itemPoJos,corpid, formId, businessType);

            UpdateExplainStageVO updateExplainStageVO = new UpdateExplainStageVO();
            updateExplainStageVO.setItems(itemPoJos);
            return updateExplainStageVO;
        } catch (XbbException e) {
            LOG.error("PaasFormService.updateExplainStage 出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    private void mendColor4Stage(List<ItemPoJo> itemPoJos, String corpid, Long formId, Integer businessType) throws XbbException {
        try {
            PaasFormExplainEntity explainEntity = proFormHelp.getExplainEntity(corpid, formId, businessType);
            FieldAttrEntity stageAttrEntity = ExplainUtil.getFieldWithFieldType(explainEntity.getExplains(), FieldTypeEnum.STAGE_THRUSTER.getType());
            if (Objects.isNull(stageAttrEntity)) {
                return;
            }
            List<ItemPoJo> sourceItems = stageAttrEntity.getItems();
            Map<String, String> valueColorMap = new HashMap<>();
            for (ItemPoJo item : sourceItems) {
                valueColorMap.put(item.getValue().toString(), item.getColor());
            }
            for (ItemPoJo itemPoJo : itemPoJos) {
                if (valueColorMap.containsKey(itemPoJo.getValue().toString())) {
                    itemPoJo.setColor(valueColorMap.get(itemPoJo.getValue().toString()));
                } else {
                    itemPoJo.setColor("#646566");
                }
            }
        } catch (XbbException e) {
            LOG.error("PaasFormService.mendColor4Stage 出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

}
